0

这是我读取 CSV 文件的 C 代码:

#include <stdio.h>
struct record
{long a,b,c;    };

int main(void)
{
    const char filename[] = "b.csv";
    FILE *file = fopen(filename, "r");

    if ( file != NULL )
    {
        char line [ 80 ];
        struct record record [ 50 ];
        size_t count, i = 0;

        while ( i < sizeof record / sizeof *record )
        {
            if ( fgets(line, sizeof line, file) == NULL )
            {
                break;
            }

            if ( sscanf(line, "%ld,%ld,%ld", &record[i].a,&record[i].b,&record[i].c) == 3 )
            {
                ++i;
            }
        }
        fclose(file);

        for ( count = i, i = 0; i < count; ++i )
        {
            printf("record[%lu]: a = %ld b = %ld c = %ld\n",
                (long unsigned)i, record[i].a, record[i].b,record[i].c);
            }
    }
    else
    {
        perror(filename);
    }
    return 0;
}

/* 文件.csv

301,36,15
302,88,75

//我的输出

record[0]: a = 301 b = 36 c = 15
record[1]: a = 302 b = 88 c = 75

*/

我对上面的代码有两个问题..

第一个问题是:/* file.csv

 301,,15
 302,88,
 ,,,34

输出应该是

record[0]: a = 301 b = 0 c = 15
record[1]: a = 302 b = 88 c = 0
record[2]: a = 0 b = 0 c = 34

第二个问题是它应该读取文件直到“eof”。这里我取 50 作为静态行号值。我应该做些什么改变?

看到我以这种方式更改了代码......

  const char* getfield(char* line, int num) {
        const char* tok;
        for (tok = strtok(line, ",");
                tok && *tok;
                tok = strtok(NULL, ",\n"))
        {
            if (!--num)
                return tok;
        }
        return NULL;
    }

    int main()
    {
        FILE* stream = fopen("b.csv", "r");
        char line[1024];
        char *pstr;int num;
         const char* value;

        while (fgets(line, 1024, stream))
        {
            char* tmp = strdup(line);
        //printf("Field 3 would be %s\n", getfield(tmp, 3));    
        value=getfield(tmp, 3);
        num =strtol(value,&pstr,10);
        printf("Field 3 would be %d\n", num);
        // NOTE strtok clobbers tmp
            free(tmp);
        }
    }
4

1 回答 1

1

而不是

sscanf(line, "%ld,%ld,%ld", &record[i].a,&record[i].b,&record[i].c)

行,您可以使用strtok_r()函数(文档)将行拆分为逗号分隔的子字符串。然后在每个子字符串上,要么执行strtol()调用(文档)以获取其整数值,要么将相应的变量设置为0如果它是一个空字符串。

您可以使用检查空字符串

if (str[0] == 0) {
    // empty
}

对于读取直到EOF,只需检查fgets()返回NULL并检查if (feof(file))- 如果到达文件末尾,fgets()设置流的 EOF 指示符FILE *,然后返回NULL

于 2012-10-30T06:24:17.703 回答