c - 用空格和分号解析 CSV

标签 c csv

我需要解析以下 CSV 文件格式:

# cat data.csv
20000530 172700;0.930200;0.930200;0.930200;0.930200;0
20000530 173500;0.930400;0.930500;0.930400;0.930500;0
20000530 173800;0.930400;0.930400;0.930300;0.930300;0
20000530 174300;0.930100;0.930100;0.930000;0.930000;0

值由字符分隔;除了第一个用空格字符分隔的。

我已尝试使用以下代码来解析 de CSV,但时间(第二个 CSV 值)未正确解析。

int read_data() {

    char _current_date[16];
    char _current_time[16];
    float _current_open;
    float _current_high;
    float _current_low;
    float _current_close;

    FILE *fp;

    fp = fopen("data.csv", "r");
    while(fscanf(fp, "%s %[ˆ;]%f;%f;%f;%f;", 
        _current_date, _current_time, 
        &_current_open, &_current_high, &_current_low, &_current_close) != EOF) {

      printf("%s\n", _current_date);
      printf("%s\n", _current_time);
    }
    fclose(fp);

}

输出是:

20000530

172700;0.930200;0.930200;0.930200;0.930200;0
0.930200;0.930200;0.930200;0
20000530
0.930200;0.930200;0.930200;0
173500;0.930400;0.930500;0.930400;0.930500;0
0.930500;0.930400;0.930500;0
20000530
0.930500;0.930400;0.930500;0
173800;0.930400;0.930400;0.930300;0.930300;0
0.930400;0.930300;0.930300;0
20000530

最佳答案

but the time (second CSV value) is not parsed correctly.

OP 的格式不消耗 ;也不是最后的 0并没有正确检查返回值。使用 == 6 , 不是 != EOF .

//                        ; not consumed
//                                    0 not consumed
while(fscanf(fp, "%s %[ˆ;]%f;%f;%f;%f;", 
    _current_date, _current_time,                             //    == 6
    &_current_open, &_current_high, &_current_low, &_current_close) != EOF) 

Parse CSV with spaces and semicolons

为了解析 OP 特定格式,以下提出了各种想法。它不是 CSV 解析器(逗号分隔值),因为 OP 不使用逗号。


  1. 测试fopen()成功

    if (fp == NULL) {
      // maybe add message
      exit(EXIT_FAILURE);
    }
    
  2. 使用 fgets()阅读 @Steve Summit

    char buf[100];   // suggest 2x expected need
    while (fgets(buf, sizeof buf, fp)) {
    
  3. 使用 sscanf()并记录用 "%n" 扫描了多少行.将文本读入字符串时使用宽度限制。 @user3121023 .我在格式中添加了一些空格以在 ; 之前允许空白.也许使用 %15[ˆ; ]避免 _current_time 中的任何空格

      int n = 0;
      sscanf(buf, "%15s %15[ˆ;] ;%f ;%f ;%f ;%f ;0 %n", 
        _current_date, _current_time, 
        &_current_open, &_current_high, &_current_low, &_current_close,
        &n);
    
  4. 测试是否n现在指向 buf 的末尾

      if (n == 0 || buf[n] != '\0') {
        // Handle failure in some manner
        break;
      }
      // else Success!
    
  5. 使用数据。添加哨兵,例如 <>到字符串输出以帮助检测意外的前导/尾随空格。

      printf("<%s>\n", _current_date);
      printf("<%s>\n", _current_time);
    }
    
  6. 清理

    fclose(fp);
    

关于c - 用空格和分号解析 CSV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49948548/

相关文章:

计数没有。 C编程中字符串中的单词(我收到空字符常量错误)

java - PHP 中是否有与 Java DisplayTag 等效的库?

Python:比较两组并将结果写入第三组

python - 通过 ctypes 将 C 库移植到 Python

c - 如何将一行中不同数量的数字分配给一个可以包含所有数字的数组?

c - GTK+ 段错误

c - 在链表开头插入节点

PHP逐行读取CSV文件

java - 在 Spark 中读取多行 CSV 文件时,是否有任何选项可以保留引号内的换行符?

java - JDBC 元数据无法识别 mysql 数据类型