C语言读取含100个整数的二进制文件结果异常,求解决方法
问题分析与解决方案
从你给出的输入序列和输出结果来看,核心问题是二进制文件中整数的存储格式与代码中读取的类型不匹配,导致读取后数值异常。
问题根源
你的输出数值(如335544320)正好是输入序列中对应数值(20)乘以2^24(16777216),这说明:
- 文件中的每个整数实际是单字节(8位)无符号数(范围0-255),但你的代码用
int(通常4字节)来读取,每次将4个字节合并为一个32位整数,从而得到了被放大2^24倍的错误结果。 - 或者文件中的整数是大端字节序的32位整数,而你的机器是小端字节序,直接读取导致字节序反转,数值错乱。
修正方案
方案1:按单字节整数读取(最可能符合你的场景)
如果文件中每个整数占1字节,修改代码使用uint8_t(单字节无符号类型)存储并读取:
#include <stdio.h> #include <stdint.h> int readBinary(char* file) { FILE *binary; size_t read_count; uint8_t addresses[100]; char local[100]; snprintf(local, sizeof(local), "assets/%s", file); binary = fopen(local, "rb"); if (binary == NULL) return 0; // 读取100个单字节元素 read_count = fread(addresses, sizeof(uint8_t), 100, binary); for (size_t i = 0; i < read_count; i++) { printf("%zu: %u\n", i, addresses[i]); } fclose(binary); // 务必关闭文件,避免资源泄漏 return 1; }
方案2:处理大端字节序的32位整数
如果文件中的整数是32位但以大端字节序存储(比如网络字节序),需要将其转换为主机字节序:
#include <stdio.h> #include <stdint.h> #include <arpa/inet.h> // 若为Windows系统,可使用winsock2.h中的ntohl函数 int readBinary(char* file) { FILE *binary; size_t read_count; uint32_t addresses[100]; char local[100]; snprintf(local, sizeof(local), "assets/%s", file); binary = fopen(local, "rb"); if (binary == NULL) return 0; read_count = fread(addresses, sizeof(uint32_t), 100, binary); for (size_t i = 0; i < read_count; i++) { // 将大端字节序转换为主机字节序 uint32_t host_value = ntohl(addresses[i]); printf("%zu: %u\n", i, host_value); } fclose(binary); return 1; }
额外注意事项
- 原代码未调用
fclose(binary),会造成文件资源泄漏,修正后的代码已补充。 fread返回值是size_t类型,原代码用int存储存在溢出风险,建议改用size_t。- 打印无符号整数时使用
%u格式符,避免符号扩展导致的错误。
内容的提问来源于stack exchange,提问作者Yuri de Melo Zorzorli Nunes
相关产品推荐
相关产品推荐

