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

C语言读取整数二进制文件结果异常,求代码排查与修复方案

问题排查与修复方案

核心问题分析

  • 文件打开模式错误:用文本模式"r"打开二进制文件,在Windows等系统中会自动转换换行符(将0x0A转为0x0D0A),破坏二进制数据的字节顺序和长度,直接引发读取错位。
  • 循环读取逻辑错误:while (fgetc(fp) != EOF)会先读取一个字节并丢弃,后续循环再读取4个字节拼接整数,相当于每次读取整数都跳过了一个字节,导致数据整体错位,这是前20个数值错误的直接原因。
  • 字节拼接顺序不匹配:代码中用a = (a <<8 | fgetc(fp))将先读取的字节作为整数高位,但大部分系统的二进制文件中整数以小端序存储(低位字节在前),这种拼接方式会导致数值解析完全错误。
  • 未处理中途EOF的情况:读取过程中若遇到EOF,fgetc返回的-1直接参与位运算,会导致整数被错误赋值。

修复方案

推荐使用标准fread函数直接读取二进制整数,避免手动拼接字节的繁琐与错误,同时修正文件打开模式:

修复后的完整代码

#include <stdio.h>
#include <stdlib.h>

void print_tab(int *tab, int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", tab[i]);
    }
    printf("\n");
}

int* new_tab(int size){
    if(size>0) {
        int *tab = malloc((size)*(sizeof(int)));
        if (tab == NULL) { // 增加内存分配失败的检查
            printf("Erreur d'allocation mémoire.\n");
            return NULL;
        }
        for (int i = 0; i < size; i++) {
            tab[i] = i + 1;
        }
        return tab;
    }
    else{
        printf("erreur: taille invalide\n");
        return NULL;
    }
}

int test_read(const char* filename) {
    FILE *fp;
    // 用二进制模式打开文件
    fp = fopen(filename, "rb");

    if (fp == NULL) {
        printf("Erreur lors de l'ouverture du fichier.\n");
        return 0;
    }

    int* tab = new_tab(100);
    if (tab == NULL) {
        fclose(fp);
        return 0;
    }

    // 直接读取100个整数
    size_t read_count = fread(tab, sizeof(int), 100, fp);
    if (read_count != 100) {
        printf("Erreur de lecture: seulement %zu entiers lus.\n", read_count);
    }

    print_tab(tab, 100);
    free(tab); // 释放内存,避免泄漏
    fclose(fp);
    return 1;
}

int main(void) {
    test_read("data/100");
    return 0;
}

手动拼接字节的替代修复(若需保留手动读取逻辑)

如果一定要手动处理字节,需修正循环逻辑与字节顺序(假设文件为小端序):

// 替换test_read中的读取循环部分
int k = 0;
int c;
while (k < 100) { // 限制读取数量,避免数组越界
    int a = 0;
    for (int i = 0; i < sizeof(int); i++) {
        c = fgetc(fp);
        if (c == EOF) {
            printf("Fin de fichier inattendue.\n");
            goto cleanup; // 提前退出并清理资源
        }
        // 小端序:低位字节先读,左移对应位数拼接
        a |= (unsigned char)c << (i * 8);
    }
    tab[k] = a;
    k++;
}
cleanup:
print_tab(tab, k);
free(tab);
fclose(fp);

关键说明

  • fread是C标准库专门用于二进制数据读取的函数,自动处理字节对齐与数量问题,比手动拼接更可靠。
  • 打开二进制文件必须使用"rb"模式,避免文本模式的自动格式转换。
  • 务必释放malloc分配的内存,避免内存泄漏。
  • 增加错误检查(如内存分配失败、读取数量不足),提升程序健壮性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 08:41:12