读取文件并显示带行号内容的C程序输出异常求助
解决读取文件并显示带行号内容的垃圾输出问题
我来帮你排查代码里的问题,你遇到的垃圾输出主要是几个关键逻辑错误导致的,咱们一步步拆解:
代码里的核心问题
- 重复调用
fgetc导致字符丢失:你的while循环里每次调用三次fgetc——第一次判断是否为EOF,第二次打印字符,第三次判断是否换行。每次fgetc都会移动文件指针,这直接导致大量字符被跳过,输出自然混乱。 lineprint函数的指针使用错误:函数里的printf ("Line %d",line);传入的是指针变量的地址值,不是指针指向的行号数值,这会打印出随机的内存地址(也就是你看到的垃圾值)。而且打印完没有换行,格式也会错乱。- 初始行号与循环逻辑错位:你在循环前提前打印了
Line 1,但后续行号更新逻辑和内容输出没有对齐,会导致行号和内容不匹配。 - 文件关闭的位置错误:如果
fopen失败(fp为NULL),后面的fclose(fp)会访问空指针,触发未定义行为。
修正后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> void lineprint(int *line) { *line = *line + 1; printf("Line %d\n", *line); // 修正:解引用指针获取行号,添加换行符 } int main() { FILE *fp; fp = fopen("sample.txt", "r"); if (fp == NULL) { printf("File not Found\n"); // 添加换行让提示更清晰 exit(EXIT_FAILURE); // 使用标准错误退出码更规范 } else { int line = 1; int ch; // 用变量保存每次读取的字符,避免重复调用fgetc printf("Line %d\n", line); // 打印第一行行号 while ((ch = fgetc(fp)) != EOF) { // 每次只读取一个字符 printf("%c", ch); // 打印当前字符 if (ch == '\n') { // 判断当前字符是否为换行 lineprint(&line); // 更新行号并打印下一行行号 } } fclose(fp); // 仅在文件成功打开时执行关闭操作 } return 0; }
额外优化:更简洁的写法
其实可以去掉单独的lineprint函数,直接在循环内处理行号,代码更紧凑:
#include <stdio.h> #include <stdlib.h> int main() { FILE *fp = fopen("sample.txt", "r"); if (!fp) { fprintf(stderr, "File not Found\n"); // 错误信息输出到标准错误流更合理 exit(EXIT_FAILURE); } int line = 1; int ch; printf("Line %d\n", line); while ((ch = fgetc(fp)) != EOF) { putchar(ch); if (ch == '\n') { printf("Line %d\n", ++line); // 直接递增并打印行号 } } fclose(fp); return 0; }
这个版本用fprintf(stderr,...)输出错误信息,符合Unix-like系统的规范——错误信息应该和正常输出分离,方便后续日志处理。
内容的提问来源于stack exchange,提问作者Gir G
相关产品推荐
相关产品推荐

