如何用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
相关产品推荐
相关产品推荐

