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
相关产品推荐
相关产品推荐

