C语言文件读取代码触发无限循环问题求助
我来帮你分析一下这个无限循环的问题,核心原因是输入格式和代码读取逻辑不匹配,再加上错误的循环终止条件共同导致的:
问题根源
1. 格式字符串与输入文件不匹配
你的fscanf格式串写的是"%d ; %d ; %s ; %d ; %d ; %d\n",默认第二列是整数类型,但输入文件第一行的第二列是字符串Visitante——当fscanf尝试用%d读取这个字符串时,无法完成整数转换,会立即停止读取,而且文件指针不会向前移动。这就导致后续每次循环都在重复读取同一个位置,永远跳不出死循环。
2. 错误的循环终止条件
你用fscanf(...) != EOF作为循环结束的判断,但fscanf只有在完全读不到任何内容(比如文件读完或者发生严重错误)时才会返回EOF。当读取部分字段失败时,它会返回成功读取的字段数量(比如这里第一次读取只成功拿到了第一个整数1,返回值是1),这个值不等于EOF,所以循环会一直执行下去。
3. 变量未正确更新
因为读取失败,除了第一次成功读取的id是1,其他变量(acompanhantes、entrada等)都保持初始值0,tipo是空字符串,所以每次循环都会输出一模一样的错误内容:1 ; 0 ; ; 0 ; 0 ; 0。
修正方案
观察你的输入文件,每行的第二列有时是字符串(比如第一行的Visitante),有时是整数(比如第二行的1),这种混合格式用fscanf固定格式读取很容易出问题,建议改用逐行读取+分割字段的方式,灵活性更高:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> void readInput() { FILE *fp; char line[256]; if ((fp = fopen("input.txt", "r")) == NULL) { printf("Erro a abrir o ficheiro, o programa vai terminar...\n"); exit(1); } // 逐行读取文件内容 while (fgets(line, sizeof(line), fp) != NULL) { // 用"; "作为分隔符分割每行的字段 char *token = strtok(line, "; "); int field_count = 0; int id = 0, acompanhantes = 0, entrada = 0, saida = 0, servico = 0; char tipo[256] = ""; while (token != NULL) { switch(field_count) { case 0: id = atoi(token); break; case 1: // 判断当前字段是数字还是字符串 if (isdigit(token[0]) || (token[0] == '-' && isdigit(token[1]))) { acompanhantes = atoi(token); } else { strncpy(tipo, token, sizeof(tipo)-1); } break; case 2: // 补全未赋值的字段:如果字段2是字符串,这里就是acompanhantes;反之则是tipo if (acompanhantes == 0 && tipo[0] == '\0') { strncpy(tipo, token, sizeof(tipo)-1); } else if (tipo[0] != '\0') { acompanhantes = atoi(token); } break; case 3: entrada = atoi(token); break; case 4: saida = atoi(token); break; case 5: servico = atoi(token); break; } field_count++; token = strtok(NULL, "; "); } // 打印处理后的字段 printf("%d ; %d ; %s ; %d ; %d ; %d\n", id, acompanhantes, tipo, entrada, saida, servico); } fclose(fp); } int main() { readInput(); }
如果你的输入文件其实是格式统一的(比如第一行的Visitante应该是第三列,可能是输入时的笔误),那只需要修正fscanf的格式串,确保和输入字段类型完全对应即可,但这种情况下还是推荐用逐行读取的方式,容错性更强。
内容的提问来源于stack exchange,提问作者Jorge

