简体   繁体   English

在 C 中读取超过 1 行的 csv 文件

[英]Read more than 1 line csv file in C

i am trying to read more than 1 line csv file,i've been sucessful to read 1 line csv file,can some one give me and example to read more than 1 line csv file?我正在尝试读取 1 行以上的 csv 文件,我已经成功读取了 1 行 csv 文件,有人可以给我和示例来读取 1 行以上的 csv 文件吗? here's the input sample :这是输入示例:

Nama,Gaji,Zakat,Gaji Bersih
Ali,1234567,,
Sofyan,2345678,,
Kholimi,3456789,,

here's my 1 line csv read source code :这是我的 1 行 csv 读取源代码:

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

int main(void)
{
    char nama[100], gaji[100], zakat[100], bersih[100];

    FILE* f = fopen("2.csv", "r");

    fscanf(f, "%s %s %s %s", nama, gaji, zakat, bersih);

    //delete comma
    size_t len = strlen(gaji);
    size_t len1 = strlen(nama);
    size_t len2 = strlen(zakat);

    gaji[len - 1] = '\0';
    nama[len1 - 1] = '\0';
    zakat[len2 - 1] = '\0';
    //delete comma

    printf("%s \t %s \t %s \t %s \n", nama, gaji, zakat, bersih);
    fclose(f);
    return 0;
}

If you want to read multiple lines with fscanf because they have the same format, I'd read the whole line with fgets and parse it with sscanf , it easier to deal with format errors this way:如果你想用fscanf读取多行,因为它们具有相同的格式,我会用fgets读取整行并用sscanf解析它,这样更容易处理格式错误:

int main(void)
{
    char nama[100], gaji[100], zakat[100], bersih[100];

    FILE* f = fopen("2.csv", "r");

    if(f == NULL)
    {
        fprintf(stderr, "Cannot open file\n");
        return 1;
    }

    char line[1024];
    size_t lineno = 0;
    while(fgets(line, sizeof line, stdin))
    {
        lineno++;
        if(sscanf(line, "%99s,%99s,%99s,%99s", nama, gaji, zakat, bersih) != 4)
        {
            fprintf(stderr, "format error on line %zu\n", lineno);
            continue;
        }

        printf("line %zu: name: %s, gaji: %s, zakat: %s, bersih: %s\n", lineno, nama, gaji, zakat, bersih);
    }

    fclose(f);
    return 0;
}

You could also use strtok to parse the lines of the CSV, for example when you don't know how many columns there are or the columns have multiple empty spaces, etc:您还可以使用strtok来解析 CSV 的行,例如当您不知道有多少列或列有多个空格等时:

int main(void)
{
    FILE* f = fopen("2.csv", "r");

    if(f == NULL)
    {
        fprintf(stderr, "Cannot open file\n");
        return 1;
    }

    char line[1024];
    size_t lineno = 0;
    const char *delim = ",\n";
    while(fgets(line, sizeof line, stdin))
    {
        lineno++;

        char *token = strtok(line, delim);
        if(token == NULL)
        {
            fprintf(stderr, "format error on line %zu\n", lineno);
            continue;
        }

        printf("line %zu:");

        do {
            printf("-%s- ", token);
        } while((token = strtok(NULL, delim)));

        putchar('\n');
    }

    fclose(f);
    return 0;
}

For a line "a,b,c,d,e" it would print "line 1: -a- -b- -c- -d- " .对于一行"a,b,c,d,e"它将打印"line 1: -a- -b- -c- -d- "

You are incorrectly reading the CSV, even regardless of the only-one-line issue.即使不考虑只有一行的问题,您也错误地读取了 CSV。

CSV is a format in which fields are separated by commas (not spaces, like your code assumes), and records are separated by newline characters; CSV 是一种格式,其中字段用逗号分隔(不是空格,就像你的代码假设的那样),记录用换行符分隔; but it's actually much more complicated than that: There are escapes, and you can have commas and/or newlines within a single datum.但实际上比这复杂得多:有转义,并且您可以在单个数据中包含逗号和/或换行符。 The format is officially documented in RFC 4180 .该格式正式记录在RFC 4180 中

But you obviously shouldn't have to reinvent the wheel and write your own CSV parsing code.但您显然不必重新发明轮子并编写自己的 CSV 解析代码。 Instead, use one of the publicly-available CSV parser libraries, such as semitrivial's csv_parser or the venerable libcsv .相反,使用公开可用的 CSV 解析器库之一,例如semitrivial 的 csv_parser或古老的libcs​​v

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

int main(void)
{
    char nama[100], gaji[100], zakat[100], bersih[100];

    FILE* f = fopen("2.csv", "r");

    while(fscanf(f, "%s %s %s %s", nama, gaji, zakat, bersih)!=EOF){

        //delete comma
        size_t len = strlen(gaji);
        size_t len1 = strlen(nama);
        size_t len2 = strlen(zakat);

        gaji[len - 1] = '\0';
        nama[len1 - 1] = '\0';
        zakat[len2 - 1] = '\0';
        //delete comma

        printf("%s \t %s \t %s \t %s \n", nama, gaji, zakat, bersih);
    }

    fclose(f);
    return 0;
}

do you want to end up with something like this?你想以这样的方式结束吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM