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

读取'\n'后while循环无法终止的C语言代码问题

解决C语言读取换行符后while循环无法终止的问题

兄弟,我仔细看了你这段代码,发现几个关键问题导致了循环停不下来的情况,咱们一步步拆解,再给你修复方案:

一、你的代码里的核心坑点

1. 文件操作的致命错误

你在while循环里每次都打开indice2.txt,而且用的是w+模式——这个模式会每次打开都清空文件里的所有内容,等于之前的数据全白存了!而且你从来没调用fclose(indice2r),文件句柄一直占着,系统资源会泄漏,后续操作也会因为文件没正确关闭而出错。

2. 循环终止条件的逻辑错误

你外层while循环用的是fscanf(fptr, "%d", &indice1) != EOF,但fscanf读取整数的时候,如果遇到非数字字符(比如换行后的字母、符号,甚至是残留的换行符),它会返回0(表示匹配失败),而不是EOF。这时候循环条件0 != EOF永远成立,直接就无限循环了!

3. 未初始化的数组导致不可预测行为

char c[1000];声明后没有初始化,数组里的元素都是随机垃圾值,你的for循环判断c[indice2] != '\n'一开始就可能是错的——比如随机值刚好是'\n',循环直接不执行;或者不是,导致数组越界,触发更奇怪的bug。

二、修复后的完整代码

#include <stdio.h>
#include <stdlib.h>

int lire(int indice1) {
    int indice2 = 0;
    char c[1000] = {0}; // 初始化数组为0,避免随机值干扰
    FILE *fptr;
    FILE *indice2r;

    // 先打开Participant.txt,必须检查是否打开成功
    fptr = fopen("Participant.txt", "r");
    if (fptr == NULL) {
        perror("Failed to open Participant.txt");
        return -1; // 返回错误码,方便调用方判断
    }

    // 打开indice2.txt,移到循环外,避免重复清空文件
    indice2r = fopen("indice2.txt", "r+");
    if (indice2r == NULL) {
        // 如果文件不存在,创建并初始化indice2为0
        indice2r = fopen("indice2.txt", "w+");
        if (indice2r == NULL) {
            perror("Failed to open indice2.txt");
            fclose(fptr); // 打开失败也要关闭已打开的文件
            return -1;
        }
        fprintf(indice2r, "0");
        rewind(indice2r); // 回到文件开头准备读取初始值
    }
    // 读取indice2的初始值,读取失败就设为0
    if (fscanf(indice2r, "%d", &indice2) != 1) {
        indice2 = 0;
    }

    // 先读取第一个整数,检查是否直接到文件末尾
    if (fscanf(fptr, "%d", &indice1) == EOF) {
        fclose(fptr);
        fclose(indice2r);
        return indice1;
    }

    // 修正循环条件:只有成功读取到整数(返回1)才继续循环
    while (fscanf(fptr, "%d", &indice1) == 1) {
        indice1++; // 保留你原代码里的自增逻辑

        // 处理当前行剩余的字符,直到换行或文件结束
        int ch;
        indice2 = 0; // 重置数组索引
        while ((ch = fgetc(fptr)) != '\n' && ch != EOF) {
            if (indice2 < 999) { // 防止数组越界,留一个位置存结束符
                c[indice2++] = ch;
            }
        }
        c[indice2] = '\0'; // 给字符数组加字符串结束符,方便后续使用

        // 更新indice2并写入文件
        indice2++; // 按你原代码的逻辑自增
        rewind(indice2r); // 回到文件开头覆盖写入
        fprintf(indice2r, "%d", indice2);
        fflush(indice2r); // 强制把缓存写入磁盘,避免数据丢失

    }

    // 所有操作完成后,必须关闭所有打开的文件
    fclose(fptr);
    fclose(indice2r);

    return indice1;
}

三、关键修复点说明

  • 文件操作优化:把indice2.txt的打开移到循环外,用r+模式(读写且不清空原有内容),如果文件不存在就创建并初始化,操作完及时关闭文件,避免资源泄漏。
  • 循环条件修正:外层while循环改成fscanf(...) == 1,只有成功读取到整数才继续循环,遇到非数字字符或EOF都会正常终止。
  • 换行符处理:用fgetc逐个读取字符直到换行符或EOF,同时跳过之前%d读取残留的空白字符,确保正确处理每行内容。
  • 数组安全:初始化数组为0,添加数组越界检查,给字符数组加结束符,避免未定义行为。
  • 错误处理:添加文件打开失败的检查,返回明确的错误码,方便调试和调用方判断。

内容的提问来源于stack exchange,提问作者Jeremy Stubbert

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:29:33