从txt文件加载Polynomial到终端时出现显示异常问题求助
多项式文件加载异常问题修复
问题现象
实现从TXT文件加载多项式到终端时出现异常:文件每行对应一个多项式,每行包含若干系数,但运行代码后,有一个系数未打印,且第三个多项式(第三行)完全不显示。
用户原代码
#include <stdio.h> #include <stdlib.h> // 补充原代码缺失的Polynom结构体定义 typedef struct { int *koeficienty; int pocetKoeficientu; } Polynom; Polynom* vytvorZeSouboru(const char *soubor, int *pocet) { FILE *file = fopen(soubor, "r"); if (file == NULL) { perror("Chyba pri otevirani souboru"); exit(EXIT_FAILURE); } *pocet = 0; // 统计文件中的行数(多项式数量) int c; while ((c = fgetc(file)) != EOF) { if (c == '\n') { (*pocet)++; } } rewind(file); Polynom *polePolynomu = (Polynom*)malloc(*pocet * sizeof(Polynom)); // 读取多项式 for (int i = 0; i < *pocet; ++i) { int pocetKoeficientu; if (fscanf(file, "%d", &pocetKoeficientu) != 1) { fprintf(stderr, "Chyba pri cteni poctu koeficientu polynomu ze souboru.\n"); exit(EXIT_FAILURE); } polePolynomu[i].koeficienty = (int*)malloc(pocetKoeficientu * sizeof(int)); polePolynomu[i].pocetKoeficientu = pocetKoeficientu; // 读取系数 for (int j = 0; j < pocetKoeficientu; ++j) { if (fscanf(file, "%d", &polePolynomu[i].koeficienty[j]) != 1) { fprintf(stderr, "Chyba pri cteni koeficientu polynomu ze souboru.\n"); exit(EXIT_FAILURE); } } } fclose(file); return polePolynomu; } void vypisPolynomy(const Polynom *polePolynomu, int pocet) { for (int i = 0; i < pocet; ++i) { printf("Polynom %d: ", i + 1); for (int j = 0; j < polePolynomu[i].pocetKoeficientu; ++j) { printf("%d ", polePolynomu[i].koeficienty[j]); } printf("\n"); } } int main() { int pocet, i; const char *cestaKSouboru = "vytvorZeSouboru.txt"; Polynom *polePolynomu = vytvorZeSouboru(cestaKSouboru, &pocet); vypisPolynomy(polePolynomu, pocet); // 释放内存 for (int i = 0; i < pocet; ++i) { free(polePolynomu[i].koeficienty); } free(polePolynomu); return 0; }
问题分析
- 多项式数量统计错误:原代码通过统计换行符数量确定多项式个数,若文件最后一行没有换行符,统计结果会比实际少1。比如3行多项式(最后一行无换行)只会统计到2个,导致第三行完全不读取。
- 跨行读取风险:使用
fscanf直接读取数字时会自动跳过所有空白字符(包括换行),如果某一行的系数个数与实际给出的系数数量不匹配,会导致后续读取错位,出现系数缺失、多项式读取异常的情况。
修复方案
方案1:修正行数统计逻辑
调整统计代码,确保即使最后一行无换行符也能正确统计多项式数量:
*pocet = 0; if (!feof(file)) { (*pocet)++; // 至少存在一行 int c; while ((c = fgetc(file)) != EOF) { if (c == '\n') { (*pocet)++; } } }
方案2:按行解析(更稳健)
改用fgets读取整行内容,再逐行解析系数,彻底避免跨行读取问题。修改后的vytvorZeSouboru函数如下(需额外引入<string.h>头文件):
#include <string.h> Polynom* vytvorZeSouboru(const char *soubor, int *pocet) { FILE *file = fopen(soubor, "r"); if (file == NULL) { perror("Chyba pri otevirani souboru"); exit(EXIT_FAILURE); } // 统计行数 *pocet = 0; char buf[1024]; while (fgets(buf, sizeof(buf), file) != NULL) { (*pocet)++; } rewind(file); Polynom *polePolynomu = (Polynom*)malloc(*pocet * sizeof(Polynom)); if (!polePolynomu) { perror("Chyba pri alokaci pameti pro pole polynomu"); fclose(file); exit(EXIT_FAILURE); } for (int i = 0; i < *pocet; ++i) { if (!fgets(buf, sizeof(buf), file)) { fprintf(stderr, "Chyba pri cteni radku souboru.\n"); exit(EXIT_FAILURE); } // 解析系数个数 int pocetKoeficientu; char *token = strtok(buf, " \n"); if (!token || sscanf(token, "%d", &pocetKoeficientu) != 1) { fprintf(stderr, "Chyba pri cteni poctu koeficientu polynomu.\n"); exit(EXIT_FAILURE); } polePolynomu[i].koeficienty = (int*)malloc(pocetKoeficientu * sizeof(int)); polePolynomu[i].pocetKoeficientu = pocetKoeficientu; if (!polePolynomu[i].koeficienty) { perror("Chyba pri alokaci pameti pro koeficienty"); exit(EXIT_FAILURE); } // 解析系数 int j = 0; while ((token = strtok(NULL, " \n")) != NULL && j < pocetKoeficientu) { if (sscanf(token, "%d", &polePolynomu[i].koeficienty[j]) != 1) { fprintf(stderr, "Chyba pri cteni koeficientu polynomu.\n"); exit(EXIT_FAILURE); } j++; } // 校验系数数量是否匹配 if (j != pocetKoeficientu) { fprintf(stderr, "Neodpovidajici pocet koeficientu u polynomu %d.\n", i+1); exit(EXIT_FAILURE); } } fclose(file); return polePolynomu; }
修复效果
- 正确统计所有多项式数量,包含最后一行无换行的场景。
- 按行解析避免跨行读取,确保每个多项式的系数都从对应行读取,不会出现错位导致的系数缺失或多项式不显示问题。
内容的提问来源于stack exchange,提问作者Bradley Kohr
相关产品推荐
相关产品推荐

