fread循环不读取所有字节,为什么字节反转?

时间:2015-10-19 18:51:58

标签: c

我的文件中包含一些测试数据"abcde"。我想一次一个字节地将数据从它读入一个uint16_t缓冲区,(我对数据的含义不感兴趣,只是它的校验和的二进制表示)但最终"e"未被阅读:

FILE *fp = fopen(filepath, "rb");
uint16_t buffer[1];
while ( fread( buffer, sizeof(uint16_t), 1, fp ) != 0 ) {
  printf("0x%x\n", *(buffer) );
}

输出:

0x6261
0x6463

如果使用uint8_t类型,则输出为:

0x61
0x62
0x63
0x64
0x65

我尝试将sizenmemb参数撤消到fread(例如while ( fread( buffer, 1, 2, fp ) != 0 )但是得到了:

0x6261
0x6463
0x6465

这可能是最不帮助的!

这给我留下了两个主要问题:

  1. 在使用fread时,如何调用uint16_t来读取所有字符(但没有上一个示例的重复数据)?
  2. 使用uint16_t时,为什么字节会反转?不应该是0x61620x6364
  3. 感激不尽的任何帮助或见解。

2 个答案:

答案 0 :(得分:3)

fread()始终读取完整记录。由于uint16_t的大小在字节大小(CHAR_BIT)为8位的机器中是2个字节,因此每次调用fread()都会在代码中读取2个字节的倍数。

您可以使用fgetc()读取单个字节,例如:

FILE *f;
uint16_t array[5];
void foo() {
    int i;
    for (i=0; i<5; i++) {
        array[i] = fgetc(f);
    }
}

字节是“反转”的,因为你可能在小端机器上运行。

答案 1 :(得分:2)

字节没有反转。你误读了输出。在您的平台上,uint160x1234表示0x34后跟0x12。没有正确的方法可以在内存中存储多字节值,您的平台就会选择这种方式。

不要将参数反转为fread。如果您读取了部分值,则不想打印它。如果您想在文件不是数据大小的偶数倍的情况下执行特定操作,请确定要编写的内容并编写代码。