通过fread从stdin读取unsigned int

时间:2014-05-21 10:00:19

标签: c stdin fread unsigned-integer

我没有编写这段代码,但我想使用它并准确理解它在做什么。

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 ++。

2 个答案:

答案 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(大端)等实验上进行实验将是有益的。

相关问题