如何用fscanf读取文件并忽略#行,实现指定格式输出?
解决fscanf处理城市列表与距离数据的问题
看起来你在处理带注释的城市和距离数据文件时遇到了两个核心问题:无法正确忽略#开头的注释行,以及fscanf格式字符串不匹配导致数据读取错误。咱们一步步来修正这个问题:
问题分析
你的原代码有几个关键问题:
- 没有先处理注释行,也没正确统计#的出现次数来区分城市列表和距离数据段
- 读取城市时的
%[^,]格式会停在第一个逗号,但没处理逗号后的空格,而且没考虑注释行后的城市列表前缀(Lista ciudades) - 读取距离时的格式字符串完全错误:
%[^ ], %[^ ], %[^\n]不适合读取空格分隔的字符串和整数,而且你把整数变量d的地址传给了%[^\n]格式,类型不匹配
修正思路
- 逐行读取并过滤注释:先用
fgets读取整行,判断是否以#开头,忽略这类行同时统计注释行的数量(我们需要区分城市列表和距离数据段) - 处理城市列表:当统计到1条注释后,遇到的第一行非注释行是城市列表,先跳过前缀
Lista ciudades,然后把逗号分隔的城市转为空格分隔输出 - 处理距离数据:当统计到2条注释后,后续每行都是空格分隔的距离数据,用
sscanf读取两个城市名和一个整数,按要求格式输出
完整修正代码
#include <stdio.h> #include <string.h> #define MAX_LINE 1024 #define MAX_CITY 64 int main() { FILE *fichero; char buffer[MAX_LINE]; char city[MAX_CITY]; char city1[MAX_CITY], city2[MAX_CITY]; int distance; int contadorAlmoadillas = 0; if ((fichero = fopen("./files/carreteras.txt", "r")) == NULL) { perror("Error al abrir el fichero"); return 1; } while (fgets(buffer, MAX_LINE, fichero) != NULL) { // 忽略空白行(可选,根据需求) if (buffer[0] == '\n' || buffer[0] == '\r') continue; // 处理以#开头的注释行 if (buffer[0] == '#') { contadorAlmoadillas++; continue; } // 处理城市列表段(第一个注释之后) if (contadorAlmoadillas == 1) { // 跳过前缀 "Lista ciudades " char *ptr = strstr(buffer, "Lista ciudades "); if (ptr != NULL) { ptr += strlen("Lista ciudades "); // 分割逗号分隔的城市 while (sscanf(ptr, "%[^,]", city) == 1) { // 输出城市,去掉前后可能的空格 printf("%s ", city); // 跳过逗号和后面的空格 ptr = strchr(ptr, ','); if (ptr == NULL) break; ptr += 2; // 跳过逗号和空格 } printf("\n"); // 可选,城市列表后换行 } } // 处理距离数据段(第二个注释之后) else if (contadorAlmoadillas == 2) { // 读取每行的两个城市和距离 if (sscanf(buffer, "%s %s %d", city1, city2, &distance) == 3) { printf("%s %s %d\n", city1, city2, distance); } } } fclose(fichero); return 0; }
代码解释
- 注释处理:用
fgets逐行读取,判断行首是否为#,是则计数并跳过 - 城市列表处理:用
strstr定位到Lista ciudades之后的内容,然后用sscanf和strchr循环分割逗号分隔的城市,转为空格输出 - 距离数据处理:直接用
sscanf读取每行的两个字符串和一个整数,按要求格式输出,避免了原代码中格式字符串不匹配的问题 - 错误处理:添加了文件打开失败的错误提示,增强代码健壮性
这样运行后就能得到你期望的输出:城市列表转为空格分隔,距离数据保留原有格式。
内容的提问来源于stack exchange,提问作者JuMoGar
相关产品推荐
相关产品推荐

