我没有编写这段代码,但我想使用它并准确理解它在做什么。
unsigned int j;
if (fread(&j,sizeof(unsigned int),1,stdin) != 1) {
if (feof(stdin)) {
fprintf(stderr,"# stdin_input_raw(): Error: EOF\n");
} else {
fprintf(stderr,"# stdin_input_raw(): Error: %s\n", strerror(errno));
}
exit(0);
}
printf("raw: %10u\n",j);
return j;
我知道代码是从stdin读取unisgned整数,但在我的测试中,输出j
不是我手工写入stdin的整数。
所以我想知道代码在做什么以及如何更改它以返回正确的输入。
Ps:我在Windows机器上使用的是Visual Studio C,而不是C ++。
答案 0 :(得分:3)
我没有足够的声望点来回复你对你的问题的评论,但你得到的原因是" 875770417"而不是" 825373492"键入1234时如下:
875770417(dec) = 0x34333231
825373492(dec) = 0x31323334
如果你仔细观察,你会发现十六进制值中的字节是向后的(十六进制中的每两个字符都是一个字节)。这是因为你在一台小端机器上。这些字节被写入stdin,因为' 1' ' 2' ' 3' ' 4&#39 ;.这是一个小端程序机器将875770417写入内存的方式,当它将相同的序列读入寄存器时,它将获得该整数,而不是您认为正确的整数。
作为注释,小端表示您将最不重要的字节写入最低地址存储器位置,因此0x1A2A3A4A
将布局为|4A|3A|2A|1A|
,其中左侧是最低地址,右侧是最高地址。在您的示例中,您在内存中有|31|32|33|34
,因此您可以阅读0x34333231
答案 1 :(得分:0)
以什么方式不起作用?
我建议如果您希望数据可移植,使用unsigned int
可能不是最好的事情,因为int
的大小不固定;像uint32_t
这样的东西可能更适合。
同样,所写的代码假定数据的字节顺序与主机相同。
此外,将sizeof(unsigned int)
替换为sizeof j
可以减少错误。
如果失败,那么输入数据的hexdump和程序的输出将是有用的。
要形成测试输入,您可以使用类似Perl的pack
函数。
在32位,64位机器,x86(小端)和ppc(大端)等实验上进行实验将是有益的。