我有一个包含以下行的输入流:
# <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
这样的第三级数据结构。必须直接从流中读取用户提供的数据结构。
编辑:请注意我们只允许对文件进行一次传递。
答案 0 :(得分:2)
现在的想法是不要使用std :: stringstream作为一条线 可以任意大,我们不想将所有内容加载到内存中 两次。所以,如果可以从中读取,那就更好了 直接输入流给用户给定的数据结构d。
Olaf 解释了上面的提取运算符,但后来我们有了新的要求:
这只适用于第一行,其中已知有一行 固定数量的元素。
和
(2)不幸的是,我不知道每个数据实例的鉴别器 结构需要用存储在三个中的信息来实例化 不同的线条。所有三条线都有不同的长度和不同 数据元素。另外,我无法更改格式。
<强>加强>
(3)所有信息都被视为无符号整数。
现在下一个问题是我们不知道数据结构究竟是什么,所以考虑到之前的情况,它似乎在某种程度上是动态的。因为我们可以将数据视为unsigned int,所以我们可以使用提取运算符,但是读入动态成员:
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.
答案 1 :(得分: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
或直接操纵流缓冲区。