如何在C++中解析基于文本的表格

4

我正在尝试使用ifstream解析以文本文件形式呈现的表格,并评估/操作每个条目。但是,由于特定项目的省略,我很难确定如何处理这个问题。请考虑以下表格:

NEW  VER  ID   NAME
1    2a   4    "ITEM ONE" (2001)
     1    7    "2 ITEM" (2002) {OCT}
     1.1  10   "SOME ITEM 3" (2003)
1         12   "DIFFERENT ITEM 4" (2004)
1    a4   16   "ITEM5" (2005) {DEC}

如您所见,有时“NEW”列中没有任何内容。 我想要做的是记录ID、名称、年份(在括号中),并注意其后是否有大括号。
当我开始做这个任务时,我寻找了“split”函数,但我意识到由于前面提到的缺失项和标题被分离,这会变得更加复杂。
我能想到的一件事是逐字阅读每一行,跟踪我看到的最新数字。一旦我遇到引号,就需要注意到我看到的最新数字是一个ID(如果我使用类似于“split”的东西,则是引号之前的数组位置),然后记录下直到下一个引号的所有内容(标题),最后开始查找其他信息的括号和大括号。然而,这似乎非常原始,我正在寻找更好的方法来解决这个问题。
我这样做是为了磨练我的C++技能并处理更大的现有数据集,因此我希望尽可能使用C ++,但如果另一种语言(我正在看Perl或Python)可以轻松完成这项任务,我可以学习如何将不同的语言与C++进行接口。我现在只是在筛选数据,这些数据最终会成为C++中的对象,因此我仍然有机会提高我的C++技能。
编辑:我也意识到只使用正则表达式就可以完成此任务,但如果可能的话,我想尝试使用不同的文件/字符串操作方法。

2
前三列是否始终具有固定宽度? - casablanca
13
从以下链接中的 token_grid 示例中选取一些如何?它们非常高效、优雅且易于使用。 - Matthieu N.
2个回答

6
如果列偏移量真正固定(没有制表符,只有真实的空格字符,如0x20),我会逐行读取它(使用string::getline),并使用固定的偏移量将其分解为一组四个字符串(string::substr)。
然后根据需要对每个4元组的字符串进行后处理。
我不会硬编码偏移量,而是将它们存储在一个单独的输入文件中,该文件描述输入的格式 - 就像SQL Server或其他DB中的表描述一样。

+1,如果列确实是固定宽度,那么这正是我要建议的。 - casablanca
1
我会把所有内容放在一个名为struct Item的结构体中,并添加operator>>(). - wilhelmtell
刚刚检查了一下文件,确实是用空格而不是制表符进行缩进。早些时候应该想到这个问题的!非常感谢。 - julian
C++ IO流默认会消耗任何空白字符。因此,字段中任意长度的制表符或空格(只要至少有一个空白字符)都不会产生影响。 - wilhelmtell
@wilhelmtell - 如果第一个之后的任何一列可能为空,那么这将是有问题的。 - Steve Townsend
显示剩余2条评论

0

类似这样:

  1. 读取第一行,找到 "ID" 并存储索引。
  2. 使用 std::getline() 读取每个数据行。
  3. 从数据行创建一个子字符串,从头行中找到的 "ID" 索引开始。使用此初始化一个 std::istringstream
  4. 使用 iss >> an_int 读取 ID。
  5. 搜索第一个 "。搜索第二个 "。搜索 ( 并记住其索引。搜索 ) 并记住该索引。从这些索引之间的字符创建一个子字符串,并使用它初始化另一个 std::istringstream。从此流中读取数字。
  6. 搜索大括号。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接