C语言读取文件异常:统计行数后无法正常读取内容
问题:统计文件行数后逐行读取出现乱码/无输出
我用C语言读取文件,先通过以下代码统计文件行数:
int main(int argc, char* argv[]) { if (argc < 2) { printf("No file specified"); exit(1); } FILE* pFile; char currentCharacter; int lines = 1; pFile = fopen(argv[1], "r"); for (currentCharacter = getc(pFile); currentCharacter != EOF; currentCharacter = getc(pFile)) { if (currentCharacter == '\n') lines++; } ... }
统计行数完成后,尝试用以下代码逐行读取文件内容:
char currentLine[255]; for (int i = 1; i <= lines; i++) { fgets(currentLine, 255, pFile); printf("%s\n", currentLine); } fclose(pFile);
但运行后输出乱码:
²a
移除循环单独调用fgets和printf则无任何输出。
注:文件已成功打开,行数统计结果正确,待读取的test.txt内容为:
test1 test2 test3
问题根源
统计行数时,getc会持续移动文件的位置指示器(文件指针),直到抵达文件末尾(EOF)。此时直接调用fgets,是从文件末尾开始读取,无法获取有效内容:
- 循环读取时,
currentLine未被正确赋值,内存中是随机垃圾数据,输出就会显示乱码 - 单独调用
fgets时,函数返回NULL,printf输出NULL指针内容无有效输出
解决方案
统计行数后,将文件位置指示器重置到文件开头,再执行逐行读取操作,有两种常用方法:
方法1:使用rewind函数
在统计行数的代码之后、逐行读取之前,添加:
rewind(pFile);
rewind会直接将文件指针重置到文件起始位置,用法简单。
方法2:使用fseek函数
也可以用fseek精确控制指针位置:
fseek(pFile, 0, SEEK_SET);
参数说明:SEEK_SET表示从文件开头偏移0字节,效果和rewind一致。
修改后的完整示例代码:
int main(int argc, char* argv[]) { if (argc < 2) { printf("No file specified"); exit(1); } FILE* pFile; char currentCharacter; int lines = 1; pFile = fopen(argv[1], "r"); if (pFile == NULL) { // 添加文件打开失败的判断 printf("Failed to open file"); exit(1); } // 统计行数 for (currentCharacter = getc(pFile); currentCharacter != EOF; currentCharacter = getc(pFile)) { if (currentCharacter == '\n') lines++; } // 重置文件指针到开头 rewind(pFile); // 逐行读取并输出 char currentLine[255]; for (int i = 1; i <= lines; i++) { if (fgets(currentLine, 255, pFile) != NULL) { // 添加fgets返回值判断 printf("%s", currentLine); // fgets已包含换行符,无需额外加\n } } fclose(pFile); return 0; }
额外优化点
- 统计行数时,如果文件为空,
lines初始化为1会导致统计错误,建议初始化为0,遇到第一个换行再递增 - 始终检查
fopen、fgets的返回值,避免空指针或读取失败的情况 fgets会读取换行符到缓冲区,所以printf时无需再加\n,否则会输出多余空行
内容的提问来源于stack exchange,提问作者Dev-Siri
相关产品推荐
相关产品推荐

