簡體   English   中英

以十六進制讀取文件給出錯誤的輸出(跳過一些十六進制值)

[英]Reading file in hex gives wrong output (skips some hex values)

我正在嘗試從 Chip8 版本的 Pong(可以在此處下載)讀取/打印十六進制指令。
這是我用來讀取 ROM 的代碼:

//Open ROM
string dir = "Test/PONG";
ifstream inf(dir.c_str(), ios::binary);

unsigned char input;
for(int i = 0; inf >> input; i++) {
    //Each loop prints 1 bytes
    //New line every 16 bytes and print line number
    if(i%16 == 0) {
        cout << endl;
        cout << setw(7) << setfill('0') << i << " ";
    }
    //2 extra spaces after 8 bytes
    else if(i%8 == 0)
        cout << "  ";
    cout << hex << setw(2) << setfill('0') << (int)input << " ";
}
cout << endl;

這是輸出的一部分:

0000000 6a 02 6b 6c 3f 6d a2 ea   da b6 dc d6 6e 00 22 d4  
0000010 66 03 68 02 60 60 f0 15   f0 07 30 00 12 1a c7 17  
0000020 77 08 69 ff a2 f0 d6 71   a2 ea da b6 dc d6 60 01  

...

這是我認為正確的輸出,這是我在終端中運行命令“hexdump -C PONG”得到的:

00000000  6a 02 6b 0c 6c 3f 6d 0c  a2 ea da b6 dc d6 6e 00  
00000010  22 d4 66 03 68 02 60 60  f0 15 f0 07 30 00 12 1a  
00000020  c7 17 77 08 69 ff a2 f0  d6 71 a2 ea da b6 dc d6  

...

在十六進制值的第一行,您可以在終端中看到兩次值“0c”,但代碼輸出跳過打印“0c”。 我不確定為什么我的代碼跳過“0c”。 我是否錯誤地讀取了文件? 命令“hexdump”是否提供了錯誤的輸出? 我可以改變閱讀文件的方式嗎?

編輯:使用 inf.get(input) 能夠讀取 '0c' 但是它也會以不同的方式輸出一些十六進制值。
例如:

6a 02 6b 0c 6c 3f 6d 0c ffffffa2 ffffffea ffffffda ffffffb6 ffffffdc ffffffd6 6e 00 22 ffffffd4 66 03 68 02 60 60 fffffff0

編輯 2: 'f's 被打印,因為一些十六進制值被讀取為負數。 所以我做了一個 if 語句來檢查輸入是否為負數,如果是負數,我將它乘以 -1 然后打印十六進制值。

編輯 3:我決定使用 stringstream 只打印負十六進制值的最后 2 個字符:

stringstream convert;
if((int)input < 0) {
     convert << hex << (int)input;
     cout << convert.str().substr(6,8) << " ";
     convert.str("");
}

編輯 4:十六進制 '0c' 表示轉義序列 '\\f',因此在打印時被忽略。 使用inf.get(input)而不是inf >> input將字符作為未格式化的字符存儲到輸入中(我認為)。 但是get()函數不能將unsigned char作為參數。 所以我必須將輸入轉換為char&
總之,我不得不將inf >> input更改為inf.get((char&)input)

來源: http : //www.cplusplus.com/reference/istream/istream/get/

Operator>> 從輸入流中讀取格式化數據(在您的情況下為 char),因此值為 12(十六進制為 0c)的 char 被視為 ASCII 換頁並被忽略(因為 32 或 0x20 的值將被視為空格) . Char 也是有符號值,a2 的十六進制值(十進制 162)將存儲為負值。 將該值提升為 int 將保留符號,並且由於互補,當打印為無符號時,您將獲得 ffff。

保持

unsigned char input;

然后讀取值使用

inf.get(static_cast<char>(input))

並打印

cout << hex << setw(2) << setfill('0') << static_cast<unsigned int>(input) << " ";

您正在使用(signed) int作為變量。 當一個有signed int為負數並以十六進制打印時,它前面將有一個或多個F數字。

我強烈建議您使用unsigned int作為您的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM