首页 > 解决方案 > 如何使用 fopen 在 c 编程中跳过注释

问题描述

我想在使用fgets.

问题是如果一行中的第一个字符开始是#,我只能跳过注释。评论以#我的文本文件开头。但是#在 myfile.txt中有一些不是一行的第一个字符,就像这样;

#Paths
A B #Path between A and B.
D C #Path between C and D.

A 是我的第一个节点,B 是我的第二个节点,当 # 到来时,我想忽略其余的文本,直到下一行。我的新节点应该是 D 和 C 等。我只能在 fopen 函数中使用“r”。我已经尝试过fgets,但它逐行读取,fgetc也无济于事。

    bool ignore_comments(const char *s)
    {
        int i = 0;
        while (s[i] && isspace(s[i])) i++;
        return (i >= 0 && s[i] == '#');
    }
    FILE *file;
    char ch[BUFSIZE];
    file = fopen("e.txt", "r");
    if (file == NULL) {
        printf("Error\n");
        fprintf(stderr, "ERROR: No file input\n");
        exit(EXIT_FAILURE);
    }
    while(fgets(ch, BUFSIZE, file) != NULL)
    {
              if (line_is_comment(ch)) {
                        // Ignore comment lines.
                        continue;
                printf("%c",*ch);
                }
     fscanf(file, "%40[0-9a-zA-Z]s", ch);
....
}

标签: cfopenfgetsfgetcfeof

解决方案


您还可以strcspn在一个简单的调用中使用修剪所有注释(如果不存在,修剪缓冲区中的行尾)。您通常会从读取的缓冲区中修剪行尾fgets()

        ch[strcspn (ch, "\r\n")] = 0;  /* trim line-ending */

如果有评论,您可以简单地将"#"字符添加到您的拒绝列表中并在那里终止。这将减少删除'#'以新格式行开头的注释并将其输出到以下位置的完整任务:

    while (fgets (ch, BUFSIZE, fp)) {   /* read every line */
        ch[strcspn (ch, "#\r\n")] = 0;  /* trim comment or line-ending */
        puts (ch);                      /* output line w/o comment */
    }

一个简短的示例,将要读取的文件作为程序的第一个参数(stdin如果没有给出参数,则默认读取),您可以这样做:

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

#define BUFSIZE 1024    /* if you need a constant, #define one (or more) */

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

    char ch[BUFSIZE];
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        perror ("file open failed");
        return 1;
    }

    while (fgets (ch, BUFSIZE, fp)) {   /* read every line */
        ch[strcspn (ch, "#\r\n")] = 0;  /* trim comment or line-ending */
        puts (ch);                      /* output line w/o comment */
    }

    if (fp != stdin) fclose (fp);       /* close file if not stdin */

    return 0;
}

示例输入文件

借用 Tom 的示例文件:)

$ cat dat/comments_file.txt
#Paths
A B #Path between A and B.
D C #Path between C and D.
E F
G H

示例使用/输出

$ ./bin/comments_remove <dat/comments_file.txt

A B
D C
E F
G H

如果您还有其他问题,请仔细查看并告诉我。


推荐阅读