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

C语言fscanf循环无法终止问题求助(含结构体存二进制文件需求)

解决fscanf无法终止及代码中的其他问题

首先,你的while循环停不下来的核心原因是错误判断了fscanf的返回值。fscanf在读取失败或到达文件末尾时返回的是EOF,而不是NULL——NULL是指针类型的空值,和fscanf的整数返回值完全不匹配,这就导致循环永远不会终止。

除此之外,代码里还有几个需要修正的细节问题,我来逐一拆解并给出修复方案:

主要错误点分析

  • fscanf返回值判断错误:应该用!= EOF替代!= NULL,更严谨的做法是检查读取的项数是否符合预期,避免出现部分读取的异常情况。
  • fscanf传参错误:linha是字符数组名,本身就是指向数组首元素的指针,不需要加&,写成fscanf(f, " %s", linha)才是正确的写法。
  • fwrite参数错误:你每次只需要写入1个struct paragem实例,第三个参数应该是1而不是2,否则会重复写入两次相同的数据。
  • 文件打开失败未终止程序:如果打开文件失败(比如f或p为NULL),后续的文件操作会导致未定义行为,应该在报错后立即终止程序。
  • 未关闭文件:操作完成后需要用fclose关闭文件,确保缓冲区的数据完全写入磁盘,避免资源泄漏。

修正后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TAM 20

struct paragem{
    char local[TAM];
    float hora;
};

int main() {
    FILE *f, *p;
    struct paragem c;
    char linha[TAM];
    int read_result;

    // 打开文本文件,失败则退出程序
    f = fopen("perc.txt", "rt");
    if(f == NULL) {
        printf("erro ao abrir ficheiro txt\n");
        exit(1);
    }

    // 打开二进制文件,失败则关闭已打开的文本文件并退出
    p = fopen("rota.bin", "wb");
    if(p == NULL) {
        printf("erro ao abrir ficheiro bin\n");
        fclose(f);
        exit(1);
    }

    // 读取开头的编号(如"23A45"),不需要处理则直接跳过
    read_result = fscanf(f, "%s", linha);
    if(read_result != 1) {
        printf("Erro ao ler o cabeçalho do ficheiro\n");
        fclose(f);
        fclose(p);
        exit(1);
    }

    // 循环读取地点和时间对,直到文件末尾或读取失败
    while(1) {
        // 读取地点
        read_result = fscanf(f, " %s", linha);
        if(read_result != 1) {
            break; // 读取失败或到文件末尾,退出循环
        }
        strcpy(c.local, linha);

        // 读取时间
        read_result = fscanf(f, " %f", &c.hora);
        if(read_result != 1) {
            break;
        }

        // 写入二进制文件,检查是否写入成功
        if(fwrite(&c, sizeof(struct paragem), 1, p) != 1) {
            printf("Erro ao escrever no ficheiro binário\n");
            break;
        }
    }

    // 关闭所有打开的文件
    fclose(f);
    fclose(p);

    return 0;
}

关键修改说明

  1. 返回值判断优化:用read_result变量接收fscanf的返回值,判断是否成功读取了1项,这样能更精准地处理文件格式错误等异常情况。
  2. 修复fscanf传参:去掉linha前的&,避免指针类型不匹配的潜在问题。
  3. 修正fwrite参数:第三个参数改为1,确保每次只写入一个结构体实例,避免重复写入。
  4. 完善错误处理:文件打开失败后立即终止程序,中途出错时关闭已打开的文件,避免资源泄漏。
  5. 添加文件关闭操作:确保所有打开的文件都被正确关闭,保证数据完全写入磁盘。

这样修改后,程序就能正确读取文本文件中的地点和时间对,写入二进制文件,并且循环会在文件末尾正常终止。

内容的提问来源于stack exchange,提问作者Walter Palma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:15:14