繁体   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