【问题标题】:Is there a c++ library that reads named columns from files?是否有从文件中读取命名列的 C++ 库?
【发布时间】:2012-04-26 01:16:50
【问题描述】:

我经常处理看起来像这样的文件(为了与 R 兼容):

# comments
# more comments
col1 col2 col3
1 a hi
2 b there
. . .

我经常想将 col2 读入向量或其他容器中。编写一个解析这种文件的函数并不难,但如果没有经过良好测试的库来为我做这件事,我会感到惊讶。有这样的图书馆吗? (正如我所说,自己动手并不难,但由于我不是 C++ 专家,所以使用允许我使用任意容器来包含任意数据类型的模板对我来说会有些麻烦。)

编辑: 我知道我想要的列的名称,但不知道这个特定文件中的列的顺序。列由未知数量的空格分隔,可能是制表符或空格(可能不是两者)。每行的第一个条目前面可能有也可能没有空格,有时这会在一个文件中发生变化,例如

number letter
 8 g
 9 h
10 i

【问题讨论】:

  • 将文件保存为 CSV 并使用 CSV 解析器?
  • 文件有多大?虽然这并不是特别困难,但很难找到一个速度不快得离谱的解决方案。
  • 通常是 100-1000 行。其中最大的是约 1000 万行。我不太关心性能,而是开发周期。
  • 我想我可能应该结束这个问题。我想我想要的东西可能对我的情况太特殊而没有标准解决方案,尽管这让我感到惊讶,因为 R 读写这样的文件,而且肯定有人同时使用 C++ 和 R。

标签: c++ file-io io


【解决方案1】:

我不知道有任何 C++ 库可以做到这一点。然而,一个简单的解决方案是使用 linux cut。您必须先删除 cmets,这可以使用 sed 轻松完成:

sed -e '/^#/d' <your_file>

然后您可以应用以下命令,仅从第三列中选择文本:

cut -d' ' -f3 <your_file>

您可以将它们与管道组合在一起以使其成为单个命令:

sed -e '/^#/d' <your_file> | cut -d' ' -f3 <your_file>

您可以以编程方式运行此命令,然后只需将每一行附加到一个 stl 容器。

//  pseudocode
while(file.hasNextLine())
{
  container << file.readNextLine();
}

有关如何在代码中实际运行cut,请参阅this answer

【讨论】:

  • 看来您必须先解析文件以删除 cmets 和声明列名的标题,然后通过管道将结果剪切。
  • 有没有办法让cut 分隔符成为由制表符和/或空格组成的可变长度的空白?它会以不同的方式处理以空格开头的行吗? perl -e 'while (&lt;&gt;) { next if /^#/; chomp; print((split)[1], "\n"); }' 会给我一个不包括 cmets 的文件中的第二列,但我看不出这比在 C++ 中读取和拆分的任何优势。
  • 我认为你是对的,如果 cut 不起作用,因为单字符分隔符不足以处理你将遇到的文件,那么在使用 C++ 进行拆分的代码。
【解决方案2】:

Boost split 可以做你想做的事,前提是你可以在空格上始终如一地分割。

【讨论】:

  • 列将由空格(可变长度、空格和/或制表符)分隔。拆分并不难 - stackoverflow.com/questions/236129/how-to-split-a-string-in-c
  • 这也是一个可行的选择。循环遍历每一行,并在空白处使用split,然后将结果列表放入二维数组中。然后你可以运行二维数组,从正确的列中选择你想要的项目。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-29
  • 1970-01-01
  • 2010-09-18
相关资源
最近更新 更多