You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言fread方法读取文件二进制数据显示异常原因排查

问题场景
  • Python读取验证:首先使用Python的read方法以二进制模式读取路径D:\CbProject\testphoto2.jpg文件,打印二进制byte类型的十六进制数据,实现代码如下:
aaa = open('D:\\CbProject\\testphoto2.jpg','rb')

a = aaa.read()
print(a)  # 十六进制显示 二进制byte类型数据
print(len(a))  # 39038

Python读取结果正常,返回数据类型为bytes,文件总长度为39038字节,文件起始二进制序列为\xff \xd8 \xff \xe0 ......,符合JPEG文件头特征。

  • C语言读取测试:随后使用C语言的fread方法读取同一文件并打印二进制形式,实现代码如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MYSIZE 39038

int main(void)
{

    FILE *fp;

    if((fp = fopen("D:\\CbProject\\testphoto2.jpg", "rb")) == NULL) {
        fprintf(stderr, "can't open file\n");
        exit(1);
    }

    char buffer[MYSIZE];
    if(fread(buffer, sizeof(buffer), 1, fp) != 1) {
        fprintf(stderr, "read failed");
        exit(1);
    }

    for (int i = 0; i < sizeof(buffer); i++) {
        printf("%2x  ", buffer[i]);
    }
    fclose(fp);
    return(0);
}
异常现象

运行上述C语言代码后,打印结果与Python读取的正确结果存在明显差异:C语言中char类型仅可存储1字节数据,单字节最大取值为0xff,但打印结果中大量数据出现多余前导f,超出单字节取值范围;同时使用%2x格式符打印时,出现单个1、2、3等不符合预期的输出。

异常原因

两个异常分别由C语言的固有特性导致:

  1. 符号扩展问题:C语言标准未强制规定char类型默认是有符号还是无符号,绝大多数x86、x64平台的编译器默认将char处理为有符号类型,取值范围为-128~127。当读取到的字节值大于等于0x80时,对应有符号char的值为负数;而printf是可变参数函数,传入的char类型参数会自动做整型提升为int类型,负数提升时会触发符号扩展,高位全部补1,比如字节值0xff对应有符号char值为-1,提升为int后值为0xffffffff,用十六进制打印就会出现多余的前导f。
  2. 格式符占位规则问题:%2x仅指定输出最小宽度为2个字符,当输出值小于0x10(即十六进制仅占1位)时,默认用空格填充宽度,不会自动补前导0,因此会出现单个数字的输出。
解决方案

针对两个问题对应修复即可:

  1. 将存储二进制数据的缓冲区类型从char改为unsigned char,无符号char取值范围为0~255,整型提升时高位统一补0,不会触发符号扩展导致的多余f问题。
  2. 将打印格式符从%2x改为%02x,格式符中的0标识指定宽度不足时用前导0填充,保证每个字节固定输出2位十六进制字符。

修正后的核心代码片段:

// 缓冲区类型改为unsigned char
unsigned char buffer[MYSIZE];
if(fread(buffer, sizeof(buffer), 1, fp) != 1) {
    fprintf(stderr, "read failed");
    exit(1);
}

for (int i = 0; i < sizeof(buffer); i++) {
    // 格式符改为%02x
    printf("%02x  ", buffer[i]);
}

内容的提问来源于stack exchange,提问作者kireirain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 22:51:16