C语言统计文件含数据行数的函数实现问题求助
C语言统计数据行数的代码问题修复
核心问题分析
你的代码输出<27>完全不符合预期,问题出在这几个关键地方:
- 函数参数无效:
get_datafile_size定义的参数是char file_name,但你根本没用到这个参数,反而硬编码了宏FNAME。而且单字符参数根本存不下文件名,必须改成字符串指针类型。 - feof循环的经典错误:
while (!feof(fp))是C语言新手常踩的坑——feof只有在尝试读取超出文件末尾后才会返回真,这会导致最后一次循环重复执行,且fgets失败后temp_str的内容是未定义的,直接用来判断会引发错误计数。 - 空行未排除:目标文件里的空行(比如管理员和员工板块之间的空行),第一个字符是
'\n',既不是#也不是空格,会被你的代码误判为有效数据行。 - 文件打开失败无处理:如果
fopen失败(比如文件路径错了、权限不够),fp会是NULL,后续操作直接触发崩溃。
修复后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "utility.h" int get_datafile_size(const char* file_name) { // 先检查文件是否成功打开 FILE* fp = fopen(file_name, "r"); if (fp == NULL) { perror("文件打开失败"); return -1; // 返回-1表示出错 } int datalines = 0; char temp_str[NAMELEN]; // 用fgets的返回值判断循环,这才是正确的读取方式 while (fgets(temp_str, NAMELEN, fp) != NULL) { // 去掉行尾的换行符,避免空行只含'\n'的情况 temp_str[strcspn(temp_str, "\n")] = '\0'; // 跳过空行、注释行、空格开头的行 if (temp_str[0] == '\0' || temp_str[0] == '#' || temp_str[0] == ' ') { continue; } datalines++; } fclose(fp); printf("<%d>", datalines); return datalines; }
关键修复说明
- 修正参数类型:把
char file_name改成const char* file_name,这样调用时可以直接传FNAME宏,也支持传入其他文件名,灵活性更高。 - 替换错误的循环条件:用
fgets(...) != NULL作为循环终止条件——fgets成功读取一行就返回非NULL,到文件末尾或读取失败就返回NULL,完美避免feof的陷阱。 - 处理换行符与空行:用
strcspn自动定位换行符并替换为'\0',之后判断字符串是否为空,彻底排除空行的干扰。 - 增加错误处理:检查
fopen的返回值,用perror打印具体错误原因,方便调试定位问题。 - 调整fgets参数:把
NAMELEN-1改成NAMELEN,因为fgets会自动在缓冲区末尾添加终止符,传入缓冲区总长度既能保证读取最大字符数,又不会溢出。
测试结果
用你提供的目标文件测试,修复后的函数会输出<12>——对应2个管理员、5个正式员工、5个学生工,共12条有效数据行,完全符合预期。
内容的提问来源于stack exchange,提问作者Crashzen
相关产品推荐
相关产品推荐

