【问题标题】:Reading in quoted CSV data without newline as endline在没有换行符的情况下读取引用的 CSV 数据作为结束行
【发布时间】:2013-09-15 01:42:18
【问题描述】:

我尝试读取的文件有问题,我不知道如何解决。

文件是 CSV,但文件文本中也有逗号,因此逗号周围有引号表示新值。

例如:

"1","hello, ""world""","and then this"  // In text " is written as ""

我想知道如何使用QFileStream 处理报价(虽然我也没有看到基本解决方案)。

此外,另一个问题是我也无法逐行阅读,因为在这些引号中可能有换行符。

在 R 中,有一个选项 quotes="" 可以解决这些问题。

C++ 中一定有一些东西。这是什么?

【问题讨论】:

  • 你试过什么? stackoverflow.com/questions/1120140/csv-parser-in-cstackoverflow.com/questions/7827274/… 从我的 POV 看来确实是您的问题的重复
  • @nyarlathotep 一个标准的 CSV 文档(据我所知)有 seperator = ,end of line = \n。在这种情况下,涉及到引号以允许这些字符出现。在这方面它是不同的:我不能简单地使用这些方法读入文件。
  • @nyarlathotep 另外,在第一个链接中,只要他们明确提到对这种情况不感兴趣。
  • 引号也在标准中。您应该更彻底地检查链接的问题; (第二个)问题中链接的库可以处理这个问题(code.google.com/p/csv-parser-cpluspluscode.google.com/p/csvpp
  • 而我尝试的是正常读取它,用逗号分隔它。这不起作用,我需要能够指出一些引用设置但我找不到它。

标签: c++ qt csv


【解决方案1】:

您可以在qt中用引号(不仅仅是引号,而是任何符号,例如'\')进行分割,只需将\放在它之前,例如:string.split("\"");string分割为'"'符号。

这是一个简单的控制台应用程序来分割你的文件(最简单的解决方案是用“,”符号分割):

// opening file split.csv, in this case in the project folder
QFile file("split.csv");
file.open(QIODevice::ReadOnly);
// flushing out all of it's contents to stdout, just for testing
std::cout<<QString(file.readAll()).toStdString()<<std::endl;
// reseting file to read again
file.reset();
// reading all file to QByteArray, passing it to QString consructor, 
// splitting that string by "," string and putting it to QStringList list
// where every element of a list is value from cell in csv file
QStringList list=QString(file.readAll()).split("\",\"",QString::SkipEmptyParts);

// adding back quotes, that was taken away by split
for (int i=0; i<list.size();i++){
    if (i!=0) list[i].prepend("\"");
    if (i!=(list.size()-1)) list[i].append("\"");
}//*/
// flushing results to stdout
foreach (QString i,list)    std::cout<<i.toStdString()<<std::endl; // not using QDebug, becouse it will add more quotes to output, which is already confusing enough

其中split.csv 包含"1","hello, ""world""","and then this",输出为:

"1"
"hello, ""world"""
"and then this"

【讨论】:

  • 这是 cvs,所以你的代码将在这一行失败:no quote,"""qute with"",""quote"""(有两个问题:没有引号,它在一个值中包含","
  • @MarekR(不是 cvs, csv 作为逗号分隔的值) - 实际上在这些情况下它会失败,这很明显,我只是假设,根据给出的示例判断,所有值都被放置在引号中。在这种情况下,如果 "," 在一个值内无论如何都无法过滤(你怎么知道,一个值内的逗号是什么以及引号中的两个值用什么逗号分隔)。不管怎样,重点是展示,如何用'"'符号分割,程序只是展示,它是如何使用的。如果将指定文本格式,我将相应地编辑帖子,目前看来这是作者想要的
  • 我不明白输出;我正在寻找一种将其仅视为 1 行的解决方案。
  • @Dualinity 再次读取QString(file.readAll()).split("\",\"",QString::SkipEmptyParts); 行,它被"," 字符串分割,而不仅仅是逗号。输出很简单。读取的每个值都打印在新行上。
  • @Dualinity 所以,你想要简单的解决方案来读取这个 csv 文件,而不是让它发挥作用,你决定下载、编译、添加到项目巨大的图书馆只是为了阅读文件?好吧,由你决定
【解决方案2】:

谷歌搜索后,我找到了一些现成的解决方案。关于qxt,请参见this article

【讨论】:

  • qxt 是巨大的,包含和构建该库只是为了解析简单的 csv 对我来说似乎是一种浪费。虽然如果文件格式差异很大我错了,那么确实一些 csv 库会很方便。
  • @Shf 我声明我更喜欢 Qt 中的解决方案。
  • @Dualinity libqxt 不是 qt。它是另一个单独的库吗?并且通过将它添加到项目中绝对不是 Qt 中的解决方案。只是可能不需要的依赖
  • 该实现似乎使用file.readAll() 一次加载所有行,对于大文件不太推荐。
  • 是的,我为此感到难过。我现在面临 200 万行,即 3gb 的数据。
猜你喜欢
  • 1970-01-01
  • 2012-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-25
  • 1970-01-01
  • 2011-11-25
相关资源
最近更新 更多