2014-07-10 15 views
5

Tôi có khối mã sau đây (KHÔNG được viết bởi tôi), thực hiện ánh xạ và giải mã các ký tự ASCII thành EBCDIC.Mã C Hoạt động khác với C++ trên Lookup

// 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]; 
    } 
} 

Định nghĩa CodeHeader

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

và phương pháp mà dường như được đem lại cho tôi vấn đề là

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

[Lưu ý, các unsigned char mảng ucpAtoe[256] được sao chép vào cuối của câu hỏi để tham khảo].

Bây giờ, tôi có một ứng dụng C cũ và chuyển đổi C++ 11 của tôi chạy song song, hai mã viết một tệp .bin lớn và có một sự khác biệt nhỏ mà tôi đã truy tìm đến mã trên. Điều gì đang xảy ra cho cả hai mã là khối

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

được nhập vào cho i = 32 và phương pháp asc2ebn trả ucTmp1 như 64 hoặc '@'cho cả C và C++ biến thể tuyệt vời. Mục nhập tiếp theo là i = 48, với giá trị này, phương thức asc2ebn trả về ucTmp1240 hoặc 'ð' và mã C++ trả về ucTmp1-16 hoặc 'ð'. Câu hỏi của tôi là tại sao tra cứu/chuyển đổi này tạo ra các kết quả khác nhau cho chính xác cùng một đầu vào và tra cứu mảng (sao chép bên dưới)?

Trong trường hợp này, mã C cũ được lấy là chính xác, vì vậy tôi muốn C++ tạo ra cùng một kết quả cho tra cứu/chuyển đổi này. Cảm ơn vì đã dành thời gian cho tôi.


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' và' -16' có cùng giá trị cho 'char', phải không? –

+3

Bạn đã thử sử dụng một cách rõ ràng 'unsigned char' trái ngược với' char' ... vì 'char' có thể là unsigned hoặc signed. –

+0

'asc2ebn()' dường như không trả về gì cả - nó được khai báo là 'void asc2ebn (...)'. – twalberg

Trả lời

2

Trong cả hai C và C++, tiêu chuẩn không yêu cầu char là một signed hoặc unsigned loại. Nó được thực hiện xác định, và rõ ràng, trình biên dịch C của bạn đã quyết định charunsigned char, trong khi trình biên dịch C++ của bạn đã quyết định nó là signed char.

Đối với GCC, cờ để làm charunsigned char-funsigned-char. Đối với MSVC, đó là /J.

+0

Cảm ơn bạn đã dành thời gian. Nhưng điều này sẽ buộc tất cả các giá trị 'char' trở thành 'unsigned'? Nếu vậy, đây không phải là những gì tôi muốn ở nơi khác trong mã 'char' giá trị được sử dụng cố ý ... Tôi đã thử sử dụng cờ này (' \ J') cho phiên bản C++ và điều này đã không giúp chuyển đổi. Tôi sẽ viết lại phương thức chuyển đổi «asc2ebn', có lẽ templating nó ... – MoonKnight

+0

@Killercam: Bạn không cần phải mẫu bất cứ điều gì, chỉ cần truy cập' szTo' và 'szFrom' đúc thành' unsigned char * 'hoặc tạo' asc2ebn của bạn 'function accept' unsigned char * '. Đó là lý do, tại sao có ba loại riêng biệt 'char',' signed char', 'unsigned char'. – mafso

+0

Điều này không giải quyết được vấn đề nhưng đưa tôi trực tiếp đi đúng hướng để cảm ơn bạn. Cuối cùng, tôi đã quá tải phương thức để lấy cả 'unsigned char *' và 'char *'. Lý do cho điều này là ở nơi khác trong mã, 'char *' được chấp nhận và các chỉ mục tiêu cực được ngăn chặn (!?) - Tôi sẽ phải xem xét điều này ... Cảm ơn tất cả mọi người đã giúp đỡ. – MoonKnight

Các vấn đề liên quan