2014-07-10 9 views
5

Ho il seguente blocco di codice (NON scritto da me), che esegue il mapping e ricodifica i caratteri ASCII in EBCDIC.Codice C che agisce in modo diverso da C++ alla ricerca

// Variables. 
CodeHeader* tchpLoc = {}; 
... 
memset(tchpLoc->m_ucpEBCDCMap, 0xff, 256); 
for (i = 0; i < 256; i++) { 
    if (tchpLoc->m_ucpASCIIMap[i] != 0xff) { 
     ucTmp2 = i; 
     asc2ebn(&ucTmp1, &ucTmp2, 1); 
     tchpLoc->m_ucpEBCDCMap[ucTmp1] = tchpLoc->m_ucpASCIIMap[i]; 
    } 
} 

La definizione CodeHeader è

typedef struct { 
    ... 
    UCHAR* m_ucpASCIIMap; 
    UCHAR* m_ucpEBCDCMap; 
} CodeHeader; 

e il metodo che sembra essere avermi dato problemi è

void asc2ebn(char* szTo, char* szFrom, int nChrs) 
{ 
    while (nChrs--) 
     *szTo++ = ucpAtoe[(*szFrom++) & 0xff]; 
} 

[Nota, il unsigned char matrice ucpAtoe[256] viene copiato alla fine del domanda per riferimento].

Ora, ho una vecchia applicazione C e la mia conversione C++ 11 in esecuzione affiancata, i due codici scrivono un file .bin di grandi dimensioni e c'è una piccola discrepanza che ho tracciato al codice precedente. Quello che sta accadendo per entrambi i codici è che il blocco

... 
    if (tchpLoc->m_ucpASCIIMap[i] != 0xff) { 
     ucTmp2 = i; 
     asc2ebn(&ucTmp1, &ucTmp2, 1); 
     tchpLoc->m_ucpEBCDCMap[ucTmp1] = tchpLoc->m_ucpASCIIMap[i]; 
    } 

viene stipulato per i = 32 e il metodo ritorna asc2ebnucTmp1 come 64 o '@'sia per la C e C++ varianti grande. La voce successiva è per i = 48, per questo valore il metodo ritorna asc2ebnucTmp1 come 240 o 'ð' e il codice C++ restituisce ucTmp1 come -16 o 'ð'. La mia domanda è: perché questa conversione/ricerca produce risultati diversi per esattamente lo stesso input e cerca array (copiato sotto)?

In questo caso il vecchio codice C è considerato corretto, quindi voglio che il C++ produca lo stesso risultato per questa ricerca/conversione. Grazie per il tuo tempo.


static UCHAR ucpAtoe[256] = { 
    '\x00','\x01','\x02','\x03','\x37','\x2d','\x2e','\x2f',/*00-07*/ 
    '\x16','\x05','\x25','\x0b','\x0c','\x0d','\x0e','\x0f',/*08-0f*/ 
    '\x10','\x11','\x12','\xff','\x3c','\x3d','\x32','\xff',/*10-17*/ 
    '\x18','\x19','\x3f','\x27','\x22','\x1d','\x35','\x1f',/*18-1f*/ 
    '\x40','\x5a','\x7f','\x7b','\x5b','\x6c','\x50','\xca',/*20-27*/ 
    '\x4d','\x5d','\x5c','\x4e','\x6b','\x60','\x4b','\x61',/*28-2f*/ 
    '\xf0','\xf1','\xf2','\xf3','\xf4','\xf5','\xf6','\xf7',/*30-37*/ 
    '\xf8','\xf9','\x7a','\x5e','\x4c','\x7e','\x6e','\x6f',/*38-3f*/ 
    '\x7c','\xc1','\xc2','\xc3','\xc4','\xc5','\xc6','\xc7',/*40-47*/ 
    '\xc8','\xc9','\xd1','\xd2','\xd3','\xd4','\xd5','\xd6',/*48-4f*/ 
    '\xd7','\xd8','\xd9','\xe2','\xe3','\xe4','\xe5','\xe6',/*50-57*/ 
    '\xe7','\xe8','\xe9','\xad','\xe0','\xbd','\xff','\x6d',/*58-5f*/ 
    '\x79','\x81','\x82','\x83','\x84','\x85','\x86','\x87',/*60-67*/ 
    '\x88','\x89','\x91','\x92','\x93','\x94','\x95','\x96',/*68-6f*/ 
    '\x97','\x98','\x99','\xa2','\xa3','\xa4','\xa5','\xa6',/*70-77*/ 
    '\xa7','\xa8','\xa9','\xc0','\x6a','\xd0','\xa1','\xff',/*78-7f*/ 
    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',/*80-87*/ 
    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',/*88-8f*/ 
    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',/*90-97*/ 
    '\xff','\xff','\xff','\x4a','\xff','\xff','\xff','\xff',/*98-9f*/ 
    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',/*a0-a7*/ 
    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',/*a8-af*/ 
    '\xff','\xff','\xff','\x4f','\xff','\xff','\xff','\xff',/*b0-b7*/ 
    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',/*b8-bf*/ 
    '\xff','\xff','\xff','\xff','\xff','\x8f','\xff','\xff',/*c0-c7*/ 
    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',/*c8-cf*/ 
    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',/*d0-d7*/ 
    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',/*d8-df*/ 
    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',/*e0-e7*/ 
    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff',/*e8-ef*/ 
    '\xff','\xff','\xff','\x8c','\xff','\xff','\xff','\xff',/*f0-f7*/ 
    '\xff','\xff','\xff','\xff','\xff','\xff','\xff','\xff' }; 
+9

'240' e' -16' hanno lo stesso valore per 'char', vero? –

+3

Hai provato a usare esplicitamente "char unsigned" invece di 'char' ... dato che' char' può essere non firmato o firmato. –

+0

'asc2ebn()' non sembra restituire nulla - è dichiarato 'void asc2ebn (...)'. – twalberg

risposta

2

Sia C e C++, lo standard non richiede char essere un tipo signed o unsigned. È stata definita l'implementazione e, apparentemente, il compilatore C ha deciso di impostare char in unsigned char, mentre il compilatore C++ ha deciso che era signed char.

Per GCC, la bandiera per rendere char per essere unsigned char è -funsigned-char. Per MSVC, è /J.

+0

Grazie per il tuo tempo. Ma non forzerà tutti i valori di 'char' a diventare' unsigned'? Se è così, questo non è quello che voglio dato che altrove i valori di 'char' del codice sono usati intenzionalmente ... Ho provato a usare questo flag (' \ J') per la versione C++ e questo non ha aiutato la conversione. Riscriverò il metodo di conversione 'asc2ebn', forse lo templando ... – MoonKnight

+0

@Killercam: non hai bisogno di creare template, basta accedere a' szTo' e 'szFrom' per' char unsigned * 'o rendere il tuo' asc2ebn 'function accetta' unsigned char * '. Questa è la ragione, perché ci sono tre tipi distinti 'char',' signed char', 'unsigned char'. – mafso

+0

Questo non ha risolto il problema, ma mi ha indirizzato direttamente sulla strada giusta, quindi grazie. Alla fine ho sovraccaricato il metodo per prendere sia 'unsigned char *' che 'char *'. La ragione per questo è altrove nel codice, 'char *' è adottato e gli indici negativi sono accettati (!?) - Dovrò esaminare questo ... Grazie a tutti per il loro aiuto. – MoonKnight

Problemi correlati