C语言文件指定行字符数函数异常:始终返回第2行长度或0
问题分析与修复
你的代码之所以出现「无论n取何值,结果要么为0要么始终是第2行长度」的问题,核心有两个错误:
1. 内层循环的逻辑漏洞
内层while ((c = fgetc(fp)) != '\n')完全没处理EOF场景:
- 如果文件总行数小于
n,这个循环会一直读取EOF(因为EOF不等于\n),陷入死循环;就算侥幸退出,也会直接读到文件末尾,返回0。 - 就算文件行数足够,若最后一行没有换行符,同样会出现异常。
另外,你注释掉的代码里if (c = EOF)是赋值操作而非判断,这会强制把c设为EOF,导致条件永远为真,直接返回0——这才是原代码总是返回0的真正原因,和你理解的「行结束时总会出现EOF」无关。
2. 资源泄漏问题
原代码打开文件后没有调用fclose(fp),会导致文件句柄泄漏,长期运行可能引发资源耗尽。
修复后的代码
int line_length(const char *filename, int n) { FILE *fp; int c; int len = 0; if ((fp = fopen(filename, "r")) == NULL) return -1; // 跳过前n-1行 while (n > 1) { c = fgetc(fp); if (c == EOF) { // 文件行数不足n,返回0(也可改为-1表示该行不存在) fclose(fp); return 0; } if (c == '\n') { n--; } } // 统计目标行的字符长度 while ((c = fgetc(fp)) != '\n' && c != EOF) { len++; } fclose(fp); return len; }
关键修复说明
- 新增EOF检查:跳过前n-1行时,每读一个字符就判断是否到文件末尾,避免死循环,同时处理行数不足的场景。
- 正确换行判断:只有读到
\n时才递减n,确保确实跳过了完整的一行。 - 关闭文件:添加
fclose(fp)释放资源,避免泄漏。 - 修正赋值错误:把原代码里的
c = EOF改为正确的c == EOF判断逻辑。
补充:行结束的场景分两种——普通行以\n结尾,文件最后一行可能以EOF结尾,所以统计长度时必须同时处理这两种情况。
内容的提问来源于stack exchange,提问作者Pepe Cuesta
相关产品推荐
相关产品推荐

