1

我有一个包含以下几行的输入流:

# <int> <int>
<some_data_type> <some_data_type> <some_data_type> ..... <some_data_type>
<some_data_type_1> <some_data_type_2> <some_data_type_3> <some_data_type_1> <some_data_type_2> <some_data_type_3> .... <some_data_type_1> <some_data_type_2> <some_data_type_3> 

在上面的流中,所有三行都是不同的,并且必须以不同的方式解析。目前,我使用的阅读方法如下:

void reader( std::istream & is, DataStructure & d ){
  std::string line;
  getline(is,line);
  std::stringstream s(line);
  //parse line 1

  getline(is,line);
  std::stringstream line2(line);
  //parse line 2

  getline(is,line);
  std::stringstream line3(line);
  //parse line 3

 }

现在的想法是根本不使用std::stringstream,因为一行可以任意大,我们不想将所有内容两次加载到内存中。因此,如果可以从输入流中直接读取到用户给定的数据结构 d 中会更好。

一个想法是利用std::istream_iterator但不幸的是不同的行有不同的解析需求。例如,在最后一行中,流中的三个元素一起构成了一个数据元素。

目前对我来说似乎合理的唯一想法是直接处理流缓冲区。如果有人可以推荐一种更好的方法,那就太好了。

注意:不能使用像std::stringstream. 必须从流中直接读取到用户提供的数据结构中。

编辑:请注意,我们只允许通过文件一次。

4

2 回答 2

2

现在的想法是根本不使用 std::stringstream,因为一行可以任意大,我们不想将所有内容加载到内存中两次。因此,如果可以从输入流中直接读取到用户给定的数据结构 d 中会更好。

奥拉夫解释了上面的提取运算符,但是我们有一个新的要求:

这仅适用于第一行,其中已知有固定数量的元素。

(2) 不幸的是,除了我知道的数据结构的每个实例都需要用存储在三个不同行中的信息来实例化之外,我没有鉴别器。所有三行都有不同的长度和不同的数据元素。另外,我无法更改格式。

(3) 所有信息都被视为无符号整数。

现在下一个问题是我们不知道数据结构实际上是什么,所以考虑到之前发生的事情,它似乎以某种方式是动态的。因为我们可以将数据视为无符号整数,所以我们可以使用提取运算符,但读入动态成员:

vector<unsigned int> myUInts;
...
inFile >> currentUInt;
myUInts.push_back(currentUInt);

但随后在哪里停止的问题开始发挥作用。是在第一行的末尾,第三行吗?如果您需要读取任意数量的无符号整数,同时仍在检查新行,那么您还需要处理空白:

inFile.unsetf(ios_base::skipws);

在没有更明确的要求的情况下,您实际处理的方式超出了我目前所能说的范围。但我猜它会是这样的形式:

 inFile >> myMember;
 char next = infile.peek()
 //skip whitespace and check for new line
 //Repeat until data structure filled, and repeat for each data structure.
于 2012-11-22T11:11:56.173 回答
1

然后根本不要使用std::getline()。为您的类型定义 istream 运算符并直接使用它们

std::istream &operator >>(std::istream &f, DataStructure &d)
{
    f >> d.member1 >> d.member2 >> ...;
    return f;
}

void reader(std::istream & is, DataStructure &d)
{
    is >> d;
}

无需摆弄std::istream_iterator或直接操作流缓冲区。

于 2012-11-22T10:30:03.693 回答