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

C语言读取格式化文件至指定标记异常,求原因及解决方案

C语言文件读取循环失效问题排查与解决

我在C语言文件操作上卡壳了:代码里的while循环本该读到"ARCS POST"就停止,但死活识别不到,而且循环里的fseek定位完全没用。先贴我的代码和目标文件内容:

我的代码

int main(int argc, char *argv[])
{
    FILE* f = fopen("/Users/[...].txt","r+");
    int input1=0; int input2=0; int input3=0;
    
    fscanf(f,"sommets : %d\n",&input1);
    printf("%d\n",input1);
    fscanf(f,"transitions : %d\n",&input1);
    printf("%d\n",input1);
    printf("%ld\n",ftell(f));
    fscanf(f,"ARCS PRE\n");
    printf("%ld\n",ftell(f));
    long int point = ftell(f);
    char word[10]="ARCS POST"; char data[100];
    while((strcmp(word, fgets(data,100,f)))!=0){ 
        fseek(f,point-ftell(f), (int) ftell(f));  //to reposition the cursor after strcmp
        fscanf(f, "%d->%d,%d\n", &input1, &input2, &input3);
        printf("%d->%d,%d\n",input1, input2, input3);
        point =ftell(f);
    }
    fclose(f);
    
    return 0;
} 

目标文件内容

sommets : 69
transitions : 9
ARCS PRE
1->2,5
1->3,7
ARCS POST
1->7,1
1->9,4
END

问题根源

  1. 字符串比较不匹配:fgets会把文件里的换行符\n也读进data缓冲区,而你定义的word是"ARCS POST"(不带换行),所以strcmp永远返回非0,循环根本停不下来。
  2. fseek用法完全错误:fseek的第三个参数必须是SEEK_SET(文件开头)、SEEK_CUR(当前位置)或SEEK_END(文件末尾),你把ftell(f)的数值传进去是非法的,直接导致定位失效。
  3. 混合fscanf和fgets的缓冲区混乱:fscanf读取后会把换行符留在输入缓冲区,后续fgets可能读到空行,进一步打乱文件指针位置。

替代解决方案(更稳健写法)

直接用fgets逐行读取,避免混合输入函数的问题,同时处理换行符确保字符串比较准确:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    FILE* f = fopen("/Users/[...].txt","r"); // 只读模式足够,无需r+
    if (!f) { // 必须检查文件是否打开成功
        perror("文件打开失败");
        return 1;
    }
    int input1=0, input2=0, input3=0;
    char line[100];

    // 读取节点数
    fscanf(f,"sommets : %d\n",&input1);
    printf("%d\n",input1);
    // 读取转换数
    fscanf(f,"transitions : %d\n",&input1);
    printf("%d\n",input1);

    // 跳过"ARCS PRE"行
    fgets(line, sizeof(line), f);

    // 循环读取直到遇到"ARCS POST"
    while (fgets(line, sizeof(line), f)) {
        // 去掉末尾的换行符(兼容不同系统的换行)
        line[strcspn(line, "\n\r")] = '\0';
        
        // 检测停止标记
        if (strcmp(line, "ARCS POST") == 0) {
            break;
        }
        
        // 解析弧的内容,检查解析是否成功
        if (sscanf(line, "%d->%d,%d", &input1, &input2, &input3) == 3) {
            printf("%d->%d,%d\n", input1, input2, input3);
        }
    }

    fclose(f);
    return 0;
}

方案优势

  • 全程用fgets逐行读取,彻底避免混合输入函数的缓冲区问题。
  • 用strcspn去掉换行符(同时处理\n和\r),确保字符串比较完全匹配。
  • 增加文件打开失败的错误处理,避免空指针操作。
  • 检查sscanf返回值,防止无效行导致的变量乱码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 07:25:18