C语言如何从文件读取指定区间字节并转换为无符号整型存入结构体
现有代码的问题
- 循环逻辑完全错误:
for(i = 0; i >= 24; i++)初始i值为0,0不满足大于等于24的条件,循环一次都不会执行 - 文件打开模式错误:读取二进制文件必须用
"rb"模式,用"r"文本模式会在部分系统下自动处理换行符,导致读取的字节和实际文件内容不一致 - 变量名不匹配:定义的文件指针是
fpc,但fgetc传入的是未定义的fp - 长度类型不匹配:16~24字节共8字节,对应64位无符号整数,你结构体中
targetsize定义为unsigned int(通常为4字节),无法容纳8字节的长度值 - 字节序没有转换:文件中存储的是网络字节序(大端),直接赋值到本地变量需要转换为CPU对应的字节序格式
最优实现方案
不用逐字节循环读取,直接用文件定位函数跳转到对应偏移量读取即可,代码更简洁性能也更高:
- 打开文件用
"rb"二进制模式 - 用
fseek直接定位到偏移16的位置 - 读取8字节数据到64位无符号整型变量
- 用字节序转换函数把网络字节序(大端)转换为本地字节序
- 记得判断所有IO操作的返回值,避免文件打开失败、读取失败等异常情况
修正后的参考代码
#include <stdio.h> #include <stdint.h> #include <endian.h> // 非Linux环境可以替换为对应平台的字节序转换头文件 struct casc_file_parsed { uint64_t targetsize; // 替换原来的unsigned int,适配8字节长度 uint64_t blocksize; uint64_t blockcount; csc_block_t* blocks; }; struct casc_file_parsed parsed_casc_file = {0}; // 二进制模式打开文件 FILE* fpc = fopen(casc_file_data, "rb"); if (fpc == NULL) { perror("打开cascade文件失败"); return; } // 定位到偏移16字节的位置 if (fseek(fpc, 16, SEEK_SET) != 0) { perror("文件定位失败"); fclose(fpc); return; } uint64_t net_target_size; // 直接读取8字节数据 if (fread(&net_target_size, sizeof(net_target_size), 1, fpc) != 1) { perror("读取targetsize失败"); fclose(fpc); return; } // 网络字节序转本地字节序 parsed_casc_file.targetsize = be64toh(net_target_size); // 后续其他逻辑 fclose(fpc);
兼容方案说明
如果需要适配非Linux环境找不到be64toh函数,可以自己实现8字节大端转本地字节序的逻辑,逐字节拼接即可。
内容的提问来源于stack exchange,提问作者ninjarubberband
相关产品推荐
相关产品推荐

