You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

读取文件并显示带行号内容的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 05:39:11