C语言读取文件时如何忽略#及之后字符?代码问题求助
解决C语言读取文件时忽略注释行并正确提取内容的问题
嘿,我来帮你搞定这个文件读取的问题~先看看你代码里的几个关键问题,再给你修正后的方案:
你的代码里的核心问题
if判断的括号完全写错了
你写的if(in = fopen("airmap1.map", "r")) == NULL,这个括号位置会让逻辑完全反转:它先把文件指针赋值给in,然后判断这个赋值操作的结果是否等于NULL,而不是判断in是否为NULL。正确的写法应该把赋值整个放进括号里,再和NULL比较。而且你原来的while循环居然写在if的大括号里,这意味着只有文件打开失败的时候才会执行循环,完全搞反了!fgets和fscanf混用导致文件指针混乱
你先用fgets读了一行到row里,紧接着又用fscanf去读文件,这会让文件指针跳来跳去,根本没法正确读取内容。同一行的内容要么用fgets处理,要么用fscanf,别混着来。注释行和有效行的处理逻辑错误
你想忽略#开头的行,但原来的代码只检查了*row == '#',如果行开头有空格的话就识别不了;而且处理有效行时用的fscanf格式字符串完全错误,%*[^\n]s这种写法会跳过整行内容,直接导致你读取到错误的单词。
修正后的代码
这里给你写一个能正确实现需求的版本,每一步都加了注释:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #define MAX_ROW_LEN 100 // 定义每行的最大长度,可根据实际调整 int main(int argc, char *argv[]) { FILE *in; char row[MAX_ROW_LEN]; // 正确判断文件是否打开失败 if ((in = fopen("airmap1.map", "r")) == NULL) { printf("Could not open file\n"); exit(1); } // 逐行读取文件内容 while (fgets(row, sizeof(row), in) != NULL) { char *current = row; // 跳过行开头的空白字符(空格、制表符等),避免注释行前有空格时识别失败 while (isspace((unsigned char)*current)) { current++; } // 如果是注释行(开头为#),直接跳过这一行 if (*current == '#') { continue; } // 分割有效行里的所有单词并输出 char *word = strtok(current, " \n\t"); // 按空格、换行、制表符拆分单词 while (word != NULL) { printf("%s ", word); word = strtok(NULL, " \n\t"); // 继续拆分下一个单词 } } fclose(in); // 记得关闭文件,养成好习惯 return 0; }
代码说明
- 文件打开判断:修正了括号位置,确保只有文件打开失败时才输出错误并退出。
- 注释行识别:先跳过行开头的空白,再判断是否以#开头,这样就算注释行前有空格也能正确识别。
- 有效行处理:用
strtok拆分每行的单词,把"cat dog"拆成"cat"和"dog","fish frog"拆成"fish"和"frog",输出结果就是你想要的cat dog fish frog。 - 细节优化:添加了
fclose(in)关闭文件,避免资源泄漏。
小优化(可选)
如果不想输出末尾的空格,可以加个简单的标记逻辑:
// 替换原来的单词输出部分 int first_word = 1; char *word = strtok(current, " \n\t"); while (word != NULL) { if (!first_word) { printf(" "); } printf("%s", word); first_word = 0; word = strtok(NULL, " \n\t"); }
这样输出就不会有末尾多余的空格了。
内容的提问来源于stack exchange,提问作者fanny lindgren
相关产品推荐
相关产品推荐

