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

C语言读取文本文件每行首个数字输出非预期值问题排查

代码异常的具体原因与修正方案

核心问题定位

  • 元素缩写变量类型定义不匹配
    原代码将abreviacao定义为单个char类型,但实际文件中的元素缩写是1-2个字符的短字符串(如H、He),必须用字符数组存储。fscanf使用%s读取字符串时,会自动在读取内容后补充结束符\0,而单个char只有1字节的存储空间,写入操作会直接越界,覆盖相邻栈内存中存放的numero_atomico变量。这也是原子序数读取值全是90-110区间乱数的根本原因——这些数值本质是被越界写入的字符ASCII码,和原子序数完全无关。这也解释了为什么之前单独修改numero_atomico的类型(char/float)始终无法解决问题:故障根源来自相邻变量的越界写入,而非变量本身的类型定义。
  • 打印格式符与传入参数不匹配
    原代码打印abreviacao时使用%s格式,但传入的是单个char的地址,即便没有越界写入,%s也会从该地址开始连续读取内存直到遇到\0,输出无意义的乱码。
  • 文件循环读取逻辑错误
    以!feof(tabela)作为循环终止条件是C语言文件操作的典型误区:feof()只有在读取操作已经触发文件末尾、读到EOF标记后才会置位文件结束状态。正常读取完全部行的瞬间,feof()尚未被触发,会导致循环多执行一次,此时所有变量没有被重新赋值,就会打印出全0类的异常值。正确的判断逻辑是直接校验fscanf的返回值,确认成功读取到全部6个字段后再执行打印操作。
  • 函数返回值与定义不匹配
    函数定义为无返回值的void类型,但代码内编写了return 0;语句,会触发编译类型不匹配警告。除此之外,原代码读取完文件后没有执行fclose操作,存在文件资源泄漏的风险。

修正后可正常运行的代码

void imprimir_tabela(){
    FILE *tabela = fopen("tabela.txt", "r");
    if(tabela == NULL){
        printf("TABELA INVALIDA OU NAO ACHADA");
        printf("erro 404");
        exit(404);
    }
    int numero_atomico;
    //  预留足够空间存储2位元素缩写+字符串结束符
    char abreviacao[3];
    char nome[20];
    float massa_atomica;
    int grupo;
    int periodo;

    //  以fscanf返回值判断读取有效性,避免feof导致的多循环问题
    while(fscanf(tabela, "%d %s %s %f %d %d", 
                &numero_atomico, abreviacao, nome, &massa_atomica, &grupo, &periodo) == 6)
    {
        printf("%d - %s - %s - Massa atomica: %0.3f - Grupo: %d - Periodo: %d\n", 
                numero_atomico, abreviacao, nome, massa_atomica, grupo, periodo);
    }
    //  读取完成后关闭文件
    fclose(tabela);
    return;
}

内容的提问来源于stack exchange,提问作者CARLOS EDUARDO NISHI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 14:15:07