【问题标题】:Reading from a CSV file and solving problems with ";"从 CSV 文件中读取并使用“;”解决问题
【发布时间】:2015-05-22 15:03:28
【问题描述】:

我有这个 CSV 文件,我必须阅读它并打印每个不同的客户(每一行都是一个客户)

IDClient;Name;Surname;Address;City;State;Postal_Code
111A;Howard;Snyder;2732 Baker Blvd.;Eugene;OR;97403
222B;Yoshi;Latimer;City Center Plaza 516 Main St.;Elgin;OR;97827
333C;John;Steel;12 Orchestra Terrace;Walla Walla;WA;99362
444D;Jaime;Yorres;87 Polk St. Suite 5;San Francisco;CA;94117

我编写了这段代码,尽管有一些警告似乎可以工作,除了; 的一些问题

int main(int argc, char const *argv[])
{   
    FILE *fp;
    fp = fopen ("clientes.txt", "rt");
    if (fp == NULL) {
        printf("Error.\n");
    }
    else {
        printf("File is open\n");
        printCustomers(fp);
        fclose(fp);
    }

    return 0;
}


void printCustomers (FILE *fp) 
{
    char id[5], first [8], last [10], adress[17], city[12], state[3], zip[6];
    printf("Printing.\n");
    fscanf(fp, "%*[^\n]\n", NULL); //Skip first line
    printf("-----------------------\n");
    while (fscanf(fp,"%4s %7s %9s %16[^\n] %11[^\n] %2s %5s", &id, &first, &last, &adress, &city, &state, &zip) == 7)
    {
        printf("IdClient: %s\nName: %s\nSurname: %s\nAdress: %s\nCity: %s\nState: %s\nZip: %s\n", id, first, last, adress, city, state, zip);
        printf("-----------------------\n");
    }

}

我的输出是这样的,你可以看到; 正在破坏输出。我认为这可以通过 fscanf 格式解决,但我不知道该怎么做。

 -----------------------
    IdClient: 111A
    Name: ;Howard
    Surname: ;Snyder;2
    Adress: 732 Baker Blvd.;
    City: Eugene;OR;9
    State: 74
    Zip: 03
    -----------------------
    IdClient: 222B
    Name: ;Yoshi;
    Surname: Latimer;C
    Adress: ity Center Plaza
    City: 516 Main St
    State: .;
    Zip: Elgin
    -----------------------
    IdClient: ;OR;
    Name: 97827
    Surname: 333C;John
    Adress: ;Steel;12 Orches
    City: tra Terrace
    State: ;W
    Zip: alla
    -----------------------
    IdClient: Wall
    Name: a;WA;99
    Surname: 362
    Adress: 444D;Jaime;Yorre
    City: s;87 Polk S
    State: t.
    Zip: Suite
    ----------------------

如果我没有很好地解释自己或缺少什么,请告诉我。

每个客户的输出都必须是这样的,也许我目前的 fscanf 有点难以达到这一点,因为并非每个客户的所有字段都具有相同的长度:

-----------------------
IdClient: 111A
Name: Howard
Surname: Snyder
Adress: 2732 Baker Blvd.
City: Eugene
State: OR
Zip: 97403
-----------------------

【问题讨论】:

  • “CSV”中的“C”代表“逗号”,而不是“分号”。
  • 是的,我确实是这么想的,并告诉了我的老师,但他仍然称其为 CSV 文件;)无论如何差异都很荒谬,只是将逗号换成分号。

标签: c csv scanf delimiter


【解决方案1】:

您可以更改您的代码

 fscanf(fp,"%4s %7s %9s %16[^\n] %11[^\n] %2s %5s",...

风格

fscanf(fp,"%4s;%7[^;];%10[^;];......

;s 作为格式字符串的一部分。那么它就不会被视为字符串输入的一部分。


注意:上述方法只是一种解决方法,如果格式发生变化,很容易中断。建议的通用方法以更稳健的方式实现相同目标:

  1. 使用fgets()读取整行
  2. 使用strtok() 进行标记,使用; 作为分隔符。
  3. >>[可选]strtol() 将令牌转换为int
  4. 打印结果。
  5. 继续直到strtok() 返回NULL。

【讨论】:

  • 但这真的会导致%s“向前看”并停在它找到的第一个;吗?我认为不会。
  • 这是假设他想要;的格式,但OP没有澄清。
  • @SouravGhosh 请参阅@BLUEPIXY 的评论,这就是我所暗示的。我也不明白%[^\n] 部分,CSV 文件 AFAIK 中没有多行字段。
  • @BLUEPIXY 我已经更新了,但不是很确定,因为我在解析时对 scanf() 家族感到不舒服。我使用第二种方法。如果需要,您能否检查我的 asnwer 中的 fscanf() 更新并进行任何更改?谢谢。
  • 我编辑并添加了如何输出。谢谢大家的回答。
猜你喜欢
  • 2018-11-18
  • 1970-01-01
  • 2017-01-16
  • 2015-09-30
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
相关资源
最近更新 更多