如果您想使用多个std::istreambuf_iterator
s 来执行此操作,那么您将需要多个 s 来执行此操作fstreams
,否则当您迭代一个(即istart++
)将影响该迭代器的所有迭代器时,fstream
这意味着下次您迭代一个(即*iarray[i]++
)时,您将跳过一个字符。这在参考文献中有更清楚的解释。考虑这个片段:
std::ifstream str;
str.open("test.data", std::ifstream::in);
std::istreambuf_iterator<char> i1 (str);
std::istreambuf_iterator<char> i2 (str);
std::cout << "i1 - " << *i1 << " i2 - " << *i2 << std::endl;
i1++;
std::cout << "i1 - " << *i1 << " i2 - " << *i2 << std::endl;
i2++;
std::cout << "i1 - " << *i1 << " i2 - " << *i2 << std::endl;
这将输出
i1 - a i2 - a
i1 - b i2 - a
i1 - b i2 - c
流中i2
似乎“跳过”b
的地方。即使您稍后分配第二个迭代器,即
std::ifstream str;
str.open("test.data", std::ifstream::in);
std::istreambuf_iterator<char> i1 (str);
std::istreambuf_iterator<char> i2;
std::istreambuf_iterator<char> iend;
int x = 0;
while (i1 != iend) {
if (x % 4 == 0) {
i2 = i1;
break;
}
x++;
i1++;
}
std::cout << *i1 << " " << *i2 << std::endl;
i1++;
std::cout << *i1 << " " << *i2 << std::endl;
i2++;
std::cout << *i1 << " " << *i2 << std::endl;
输出保持不变 -
i1 - a i2 - a
i1 - b i2 - a
i1 - b i2 - c
为什么?
因为在任何一种情况下,两个迭代器都作用于同一个流对象,并且每次迭代一个它都会从流中删除一个字符。在有问题的代码中,每个迭代器 ( istart
, iarray[i]
) 都作用于同一个流对象,因此其中一个迭代器的每次迭代都会char
从流中删除 a。然后,输出很快就会成为未定义行为的结果,因为迭代超出流的末尾是未定义的(并且由于迭代器一起迭代,因此您可以快速到达它)。
如果您想按照大纲的方式执行此操作,您只需要多个fstream
对象,例如
#include <fstream>
#include <string>
#include <iostream>
int main(int argn, char** argv) {
std::ifstream str2;
str2.open ("test.data", std::ifstream::in);
int nbline = 3;
int nbcolumn = 4;
int x = 0;
std::istreambuf_iterator<char> istart (str2);
std::istreambuf_iterator<char> iend ;
std::ifstream* streams = new std::ifstream[nbline];
for (int ii = 0; ii < nbline; ii++) {
streams[ii].open("test.data", std::ifstream::in);
}
std::istreambuf_iterator<char>* iarray = new std::istreambuf_iterator<char>[nbline];
for (int ii = 0; ii < nbline; ii ++) {
iarray[ii] = std::istreambuf_iterator<char> (streams[ii]);
}
int idx = 0;
while (istart != iend) {
if (x % nbcolumn == 0) {
std::advance(iarray[x/nbcolumn], (nbcolumn+1)*idx);
idx++;
}
x++;
istart++;
}
for (int ii = 0; ii < nbcolumn; ii ++) {
for (int jj = 0; jj < nbline; jj ++) {
std::cout << *iarray[jj]++ << "\t";
}
std::cout << std::endl;
}
}
这会产生您期望的输出,
a e j
b f k
c g l
d h m
相对于其他建议的方法,我无法评论此方法的速度,但这就是您使用此方法执行您所要求的操作的方式。