C 将文本文件数据读入结构数组(同时忽略注释行)

C 将文本文件数据读入结构数组(同时忽略注释行),c,arrays,struct,file-io,fgets,C,Arrays,Struct,File Io,Fgets,概述: 以下程序的目的是将数据逐行从输入文件读取到结构数组中,同时忽略输入文件中以“#”字符开头的任何注释行。。然后,程序应遍历结构数组并打印内容,以确认程序按预期工作 下面是输入文件的一个示例,其中显示了3行非注释数据。编译之前,非注释行的数量是已知的,如下面的尝试所示,行int Nbodies=3 30 07 6991 # some comment 28 02 4991 09 09 2991 注意:请注意,在决定发布此问题之前,已经研究了以下SO问题: Dilema: 当没有注释行时

概述:

以下程序的目的是将数据逐行从输入文件读取到结构数组中,同时忽略输入文件中以“#”字符开头的任何注释行。。然后,程序应遍历结构数组并打印内容,以确认程序按预期工作

下面是输入文件的一个示例,其中显示了3行非注释数据。编译之前,非注释行的数量是已知的,如下面的尝试所示,行
int Nbodies=3

30 07 6991
# some comment
28 02 4991
09 09 2991
注意:请注意,在决定发布此问题之前,已经研究了以下SO问题:

Dilema:

当没有注释行时,程序可以成功地将行读入结构数组并打印内容。程序还可以成功地检测以“#”字符开头的行,从而将其视为注释行。问题在于,即使检测到注释行,程序仍试图将该行错误地读入结构数组

这是预期输出:

30 07 6991
28 02 4991
09 09 2991
以下是实际(和不正确的)输出,它似乎忽略了未注释数据的最后一行:

30 07 6991
-842150451 -842150451 -842150451
28 02 4991
当前尝试:

fgets
用于读取每一行,从而确定行的开头是否以
开头。此注释检查在
IF
语句中执行,该语句在
FOR
循环条件中增加
Nbodies
变量(这样迭代就不会在注释行上“浪费”,如果有意义的话)。在此之后,
sscanf
用于尝试将当前非注释行的三个值读入结构数组中
fscanf
也是一种尝试过的方法,但不起作用。使用
继续
?它似乎没有按预期的那样进行

迄今为止的代码:

#include "stdio.h"

#define EXIT_SUCCESS 0
#define EXIT_FAILURE !EXIT_SUCCESS

int main() {

    typedef struct {
        int a1, b1, c1;
    }DATA;

    FILE *file = fopen("delete.nbody", "r");
    if (file == NULL)
    {
        printf(stderr, "ERROR: file not opened.\n");
        return EXIT_FAILURE;
    }

    int Nbodies = 3;
    int comment_count = 0;
    DATA* data = malloc(Nbodies * sizeof * data); // Dynamic allocation for array
    char line[128]; // Length won't be longer than 128
    int x;
    for (x = 0; x < Nbodies; x++)
    {
        fgets(line, sizeof(line), file);
        if (line[0] == '#')
        {
            comment_count++;
            Nbodies++;// Advance Nbodies so that iteration isn't 'wasted' on a comment line
            continue;
        }

        // QUESTION: doesn't "continue;" within above IF mean that the 
        // following sscanf shouldn't scan the comment line?
        sscanf(line, "%d %d %d", &data[x].a1, &data[x].b1, &data[x].c1);
    }

    // Nbodies - comment_count, because Nbodies advanced
    // every time a comment was detected in the above FOR loop
    for (x = 0; x < Nbodies - comment_count; x++)
    {
        printf("%d %d %d\n", data[x].a1, data[x].b1, data[x].c1);
    }

    return (EXIT_SUCCESS);
}
#包括“stdio.h”
#定义退出\u成功0
#定义退出失败!退出成功
int main(){
类型定义结构{
int a1、b1、c1;
}数据;
FILE*FILE=fopen(“delete.nbody”、“r”);
if(file==NULL)
{
printf(stderr,“错误:文件未打开。\n”);
返回退出失败;
}
int Nbodies=3;
int comment_count=0;
DATA*DATA=malloc(Nbodies*sizeof*DATA);//数组的动态分配
字符行[128];//长度不会超过128
int x;
对于(x=0;x
问题:

有人知道为什么这个程序不起作用吗?我本以为
continue
这个词在被检测到时会跳过sscanf来读取注释行。在此方面如有任何帮助,将不胜感激。

  • 仅当您实际指定
  • 检查两个条件:数组索引和输入成功

(x=0;x{ int rc; 如果(!fgets(行、行大小、文件))中断; 如果(第[0]行='#') { 注释_count++; 继续; } rc=sscanf(第%d%d%d行,&data[x].a1,&data[x].b1,&data[x].c1); 如果(rc!=3)继续; x++; }
  • 仅当您实际指定
  • 检查两个条件:数组索引和输入成功

(x=0;x{ int rc; 如果(!fgets(行、行大小、文件))中断; 如果(第[0]行='#') { 注释_count++; 继续; } rc=sscanf(第%d%d%d行,&data[x].a1,&data[x].b1,&data[x].c1); 如果(rc!=3)继续; x++; } 如果你收到评论,不要增加Nbodies

这是错误的方法,因为
数据
由于预循环
malloc

并且,您将在
数据
数组中引入一个间隙

这里有一个更好的方法,使
数据
只包含有效数据。注释行完全“不可见”(即它们不影响数据的计数):

int
main()
{
类型定义结构{
int a1,
b1,
c1;
}数据;
FILE*FILE=fopen(“delete.nbody”、“r”);
if(file==NULL){
printf(stderr,“错误:文件未打开。\n”);
返回退出失败;
}
int Nbodies=3;
int comment_count=0;
//阵列的动态分配
DATA*DATA=malloc(Nbodies*sizeof*DATA);
字符行[128];//长度不会超过128
int x;
#如果0
对于(x=0;xfor (x = 0; x < Nbodies; ) {
        int rc;
        if ( !fgets(line, sizeof line, file)) break;
        if (line[0] == '#')
        {
            comment_count++;
            continue;
        }

        rc = sscanf(line, "%d %d %d", &data[x].a1, &data[x].b1, &data[x].c1);
        if (rc != 3) continue;
        x++; 
    }
int
main()
{

    typedef struct {
        int a1,
         b1,
         c1;
    } DATA;

    FILE *file = fopen("delete.nbody", "r");

    if (file == NULL) {
        printf(stderr, "ERROR: file not opened.\n");
        return EXIT_FAILURE;
    }

    int Nbodies = 3;
    int comment_count = 0;

    // Dynamic allocation for array
    DATA *data = malloc(Nbodies * sizeof *data);

    char line[128]; // Length won't be longer than 128
    int x;

#if 0
    for (x = 0; x < Nbodies; x++) {
        fgets(line, sizeof(line), file);

        if (line[0] == '#') {
            comment_count++;
            // Advance Nbodies so that iteration isn't 'wasted' on a comment
            Nbodies++;
            continue;
        }

        // QUESTION: doesn't "continue;" within above IF mean that the
        // following sscanf shouldn't scan the comment line?
        sscanf(line, "%d %d %d", &data[x].a1, &data[x].b1, &data[x].c1);
    }
#else
    int inc = 1;
    for (x = 0; x < Nbodies; x += inc) {
        fgets(line, sizeof(line), file);

        inc = (line[0] != '#');

        if (! inc) {
            comment_count++;
            continue;
        }

        // QUESTION: doesn't "continue;" within above IF mean that the
        // following sscanf shouldn't scan the comment line?
        sscanf(line, "%d %d %d", &data[x].a1, &data[x].b1, &data[x].c1);
    }
#endif

    // Nbodies - comment_count, because Nbodies advanced
    // every time a comment was detected in the above FOR loop
#if 0
    for (x = 0; x < Nbodies - comment_count; x++) {
#else
    for (x = 0; x < Nbodies; x++) {
#endif
        printf("%d %d %d\n", data[x].a1, data[x].b1, data[x].c1);
    }

    return (EXIT_SUCCESS);
}