Если вы хотите сделать это, используя несколько std::istreambuf_iterator
с, вам понадобится несколько 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
из потока.Выходные данные быстро становятся результатом неопределенного поведения, поскольку итерации за end-of-stream не определены (и поскольку итераторы итерируют вместе, вы быстро достигаете его).
Если вы хотите сделать это так, как у вас есть контур, вам просто нужно несколько 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
Я не могу комментировать скорость этого метода относительно других, которые были предложены, но именно так вы будете делать то, что вы просите, используя этот метод.