【问题标题】:How to parse text-based table in C++如何在 C++ 中解析基于文本的表
【发布时间】:2010-11-08 20:07:34
【问题描述】:

我正在尝试使用 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}

如您所见,有时“新”列中没有任何内容。我要做的是记下 ID、名称、年份(在括号中),并注意后面是否有大括号。

当我开始这样做时,我寻找了一个“拆分”功能,但我意识到它会因为前面提到的缺失项和标题分离而变得有点复杂。

我能想到的一件事是逐字阅读每一行,跟踪我看到的最新数字。一旦我打了引号,请注意我看到的最新数字是一个 ID(如果我使用了类似拆分的东西,则数组位置就在引号之前),然后记录所有内容,直到下一个引号(标题) ,然后最后,开始寻找其他信息的括号和大括号。但是,这似乎很原始,我正在寻找更好的方法来做到这一点。

我这样做是为了提高我的 C++ 技能并使用更大的现有数据集,所以如果可能的话,我想使用 C++,但是如果另一种语言(我正在看 Perl 或 Python)让这变得非常简单,我可以学习如何将不同的语言与 C++ 接口。我现在要做的只是筛选数据,这些数据最终将成为 C++ 中的对象,所以我仍然有机会提高我的 C++ 技能。

编辑:我也意识到这可以仅使用正则表达式来完成,但如果可能的话,我想尝试使用不同的文件/字符串操作方法。

【问题讨论】:

标签: c++ string file-io tabular


【解决方案1】:

如果列偏移量确实是固定的(没有制表符,只有真正的空格字符 a la 0x20)我会一次读取一行(string::getline)并使用固定的偏移到一组四个字符串 (string::substr)。

然后根据需要对每个 4 元组字符串进行后处理。

我不会对偏移量进行硬编码,而是将它们存储在一个单独的输入文件中,该文件描述输入的格式 - 就像 SQL Server 或其他 DB 中的表描述。

【讨论】:

  • +1,如果列确实是固定宽度,这正是我所建议的。
  • 就此而言,您可以根据标题行相当容易地计算出列宽。
  • 我会将所有内容放在具有operator>>()struct Item 中。
  • 刚刚检查了文件,它确实是间隔的,而不是标签。早该想到的!非常感谢。
  • C++ IO 流默认使用任何空格。因此,字段之间任意长度的制表符或空格(只要至少有一个空白字符)都没有区别。
【解决方案2】:

类似这样的:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    相关资源
    最近更新 更多