istream_iterator
s are very useful for reading sequences of numbers or other parsable data into STL containers without explicit loops in the code.
Using explicit container size:
std::vector<int> v(100);
std::copy(std::istream_iterator<int>(ifs), std::istream_iterator<int>(),
v.begin());
or with inserting iterator:
std::vector<int> v;
std::copy(std::istream_iterator<int>(ifs), std::istream_iterator<int>(),
std::back_inserter(v));
Note that the numbers in the input file may be divided by any number of any whitespace characters and newlines.
As istream::operator>>
reads text until a whitespace symbol, it may be used in while
condition to parse complex data tables. For example, if we have a file with two real numbers followed by a string (without spaces) on each line:
1.12 3.14 foo
2.1 2.2 barr
it may be parsed like this:
std::string s;
double a, b;
while(ifs >> a >> b >> s) {
std::cout << a << " " << b << " " << s << std::endl;
}
Any range-manipulating function may be used with std::istream_iterator
ranges. One of them is std::transform
, which allows to process data on-the-fly. For example, let's read integer values, multiply them by 3.14 and store the result into floating-point container:
std::vector<double> v(100);
std::transform(std::istream_iterator<int>(ifs), std::istream_iterator<int>(),
v.begin(),
[](int val) {
return val * 3.14;
});