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

如何用C语言逐行读取TXT文件?处理行内可变整数

解决按行处理文件中I/S指令的问题

输入文件格式如下:

I 15 3 15 10 10 20  
S -5 3 15 82  
I -20 80 -4 10  
S 4 -20 8

每行以'I'(插入)或'S'(搜索)开头,后续跟随数量不定的整数。需要根据开头字符对该行整数执行对应操作,但原代码中用fscanf无法判断行尾(C标准中没有EOL这类判断条件),想改用fgets但不清楚具体用法,原代码如下:

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

void readFileLines(char** argv)
{
    FILE* fp = fopen(argv[1], "r");
    char read;
    while(fscanf(fp, "%c	", &read) != EOF)
    {
        //scan first letter in line until EOF
        if(read == 'I')
        {
            //loop through all values in Line
            int data;
            printf("Inputting...");
            while(fscanf(fp, "%i	", &data) != EOL) //ERROR (EOL DOESNT WORK)
            {
                //iterate rest of line values til end of line
                printf("%d	", data);
                
            }
        }
        else if(read == 'S')
        {
            int data;
            printf("Searching...");
            while(fscanf(fp, "%d	", &data) != EOL) // ERROR (EOL DOESNT WORK)
            {
                printf("%d	", data);
          
            }
        }

        printf("\n");
        //iterate through to next line in order to scan different letteer
    }
   }

int main(int argc, char** argv)
{
    
     readFileLines(argv);

    return EXIT_SUCCESS;
}

解决方案

核心思路是先用fgets读取整行内容,再对每行单独解析,这样就能精准处理每行的指令和整数,不会出现跨行读取的问题。以下是两种可行实现方式:

方法一:用sscanf循环解析整行

通过fgets获取整行后,用sscanf配合%n标记解析位置,循环提取指令和整数:

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

void readFileLines(char** argv)
{
    FILE* fp = fopen(argv[1], "r");
    if (fp == NULL) { // 增加文件打开失败的错误处理
        perror("Failed to open file");
        return;
    }

    char line[256];
    while (fgets(line, sizeof(line), fp) != NULL) {
        char cmd;
        int data;
        int pos = 0; // 记录当前解析到的字符串位置

        // 解析开头的指令字符
        if (sscanf(line + pos, "%c %n", &cmd, &pos) != 1) {
            continue; // 跳过无效行
        }

        if (cmd == 'I') {
            printf("Inputting...");
            // 循环解析后续所有整数
            while (sscanf(line + pos, "%d %n", &data, &pos) == 1) {
                printf("%d ", data);
            }
        } else if (cmd == 'S') {
            printf("Searching...");
            while (sscanf(line + pos, "%d %n", &data, &pos) == 1) {
                printf("%d ", data);
            }
        } else {
            printf("Unknown command: %c", cmd);
        }
        printf("\n");
    }

    fclose(fp); // 记得关闭文件
}

int main(int argc, char** argv)
{
    if (argc < 2) { // 增加参数检查,避免未传文件名
        printf("Usage: %s <filename>\n", argv[0]);
        return EXIT_FAILURE;
    }
    readFileLines(argv);
    return EXIT_SUCCESS;
}

方法二:用strtok分割字符串解析

如果需要兼容多种分隔符(比如空格、制表符),可以用strtok分割每行字符串,再逐个转换为整数:

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

void readFileLines(char** argv)
{
    FILE* fp = fopen(argv[1], "r");
    if (fp == NULL) {
        perror("Failed to open file");
        return;
    }

    char line[256];
    while (fgets(line, sizeof(line), fp) != NULL) {
        // 去掉换行符,避免后续分割出空token
        line[strcspn(line, "\n")] = '\0';

        char* token = strtok(line, " \t"); // 支持空格和制表符分割
        if (token == NULL) continue;

        char cmd = token[0];
        if (cmd == 'I') {
            printf("Inputting...");
            token = strtok(NULL, " \t");
            while (token != NULL) {
                int data = atoi(token);
                printf("%d ", data);
                token = strtok(NULL, " \t");
            }
        } else if (cmd == 'S') {
            printf("Searching...");
            token = strtok(NULL, " \t");
            while (token != NULL) {
                int data = atoi(token);
                printf("%d ", data);
                token = strtok(NULL, " \t");
            }
        } else {
            printf("Unknown command: %c", cmd);
        }
        printf("\n");
    }

    fclose(fp);
}

int main(int argc, char** argv)
{
    if (argc < 2) {
        printf("Usage: %s <filename>\n", argv[0]);
        return EXIT_FAILURE;
    }
    readFileLines(argv);
    return EXIT_SUCCESS;
}

关键说明

  • fgets会读取整行内容(包含换行符),直到遇到换行符或文件结束,返回的字符串以\0结尾。
  • 方法一中的%n是sscanf的特殊格式,用于记录本次读取的字符数,方便后续偏移解析位置。
  • 方法二中strcspn用于定位换行符并替换为\0,避免分割时出现无效空token;atoi负责将分割出的字符串转换为整数。
  • 两种方法都增加了错误处理逻辑,提升程序健壮性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 10:25:58