Stream iterators
Stream iterator将stream和iterator联系起来,通过iterator,进而连接了algorithm,因此通过stream iterator,可以将algorithm应用于stream。
关于stream,参见C++\Library\Standard-library\Input-output-library
。
geeksforgeeks std::istream_iterator
and std::ostream_iterator
in C++ STL
NOTE: 这篇文章论述得非常好
ostream_iterator
把这两种output stream iterator放到一起来进行介绍。
cppreference std::ostream_iterator
cppreference std::ostreambuf_iterator
std::ostream_iterator VS std::ostreambuf_iterator
在std::ostream_iterator中有这样的描述:
When writing characters, std::ostreambuf_iterator is more efficient, since it avoids the overhead of constructing and destructing the sentry object once per character.
显然std::ostream_iterator需要sentry object,那sentry object是什么呢?
a boolean flag indicating if the the end of file condition has been reached
istream_iterator
cppreference std::istream_iterator
std::istream_iterator
is a single-pass input iterator that reads successive objects of type T
from the std::basic_istream object for which it was constructed, by calling the appropriate operator>>
.
NOTE:
std::istream_iterator
的特性:
- single pass
- input iterator
The default-constructed std::istream_iterator
is known as the end-of-stream iterator. When a valid std::istream_iterator
reaches the end of the underlying stream, it becomes equal to the end-of-stream iterator. Dereferencing or incrementing it further invokes undefined behavior.
NOTE: 在下面的example中,就用到了“The default-constructed
std::istream_iterator
is known as the end-of-stream iterator. ”来标志end-of-stream。
Notes
When reading characters, std::istream_iterator
skips whitespace by default (unless disabled with std::noskipws or equivalent), while std::istreambuf_iterator does not. In addition, std::istreambuf_iterator is more efficient, since it avoids the overhead of constructing and destructing the sentry object once per character.
Example
#include <iostream>
#include <sstream>
#include <iterator>
#include <numeric>
#include <algorithm>
int main()
{
std::istringstream str("0.1 0.2 0.3 0.4");
std::partial_sum(std::istream_iterator<double>(str),
std::istream_iterator<double>(),
std::ostream_iterator<double>(std::cout, " "));
std::istringstream str2("1 3 5 7 8 9 10");
std::cout << "\nThe first even number is " <<
*std::find_if(std::istream_iterator<int>(str2),
std::istream_iterator<int>(),
[](int i){return i%2 == 0;})
<< ".\n";
//" 9 10" left in the stream
}
NOTE:
std::istream_iterator<double>()
原来标识end-of-stream。
cppreference std::istreambuf_iterator
Example: output container
Output to std out
取自: stackoverflow How to use ostream_iterator<> to output result to a newfile?
// ostream_iterator example
#include <iostream> // std::cout
#include <iterator> // std::ostream_iterator
#include <vector> // std::vector
#include <algorithm> // std::copy
int main()
{
std::vector<int> myvector;
for (int i = 1; i < 10; ++i)
{
myvector.push_back(i * 10);
}
std::ostream_iterator<int> out_it(std::cout, ", ");
std::copy(myvector.begin(), myvector.end(), out_it);
return 0;
}
// g++ test.cpp
取自: https://www.tenouk.com/cpluscodesnippet/cplusstlostream_iteratorconstructor.html
// C++ STL ostream_iterator::ostream_iterator, constructor
#include <iterator>
#include <vector>
#include <iostream>
using namespace std;
int main(void)
{
// C++ STL ostream_iterator for stream cout
cout << "Inserting & printing elements: " << endl;
ostream_iterator<int> intOut(cout, "\n");
// insert data
*intOut = 12;
intOut++;
*intOut = 33;
intOut++;
int i;
// vector container
vector<int> vec;
// push/insert data into vec vector
for (i = 10; i <= 15; ++i)
{
vec.push_back(i);
}
cout << "Operation: with and without delimiter..." << endl;
// write elements to standard output stream
cout << "Elements output without delimiter: ";
copy(vec.begin(), vec.end(), ostream_iterator<int>(cout));
cout << endl;
// write elements with delimiter " " to output stream
cout << "Elements output with delimiter: ";
copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return 0;
}
// g++ test.cpp
Output to file
取自: https://stackoverflow.com/a/22876942
// ostream_iterator example
#include <iostream> // std::cout
#include <iterator> // std::ostream_iterator
#include <vector> // std::vector
#include <algorithm> // std::copy
#include <fstream> // std::ofstream
int main()
{
std::vector<int> myvector;
for (int i = 1; i < 10; ++i)
{
myvector.push_back(i * 10);
}
std::ofstream of("myoutput.txt");
std::ostream_iterator<int> out_it(of, ", ");
std::copy(myvector.begin(), myvector.end(), out_it);
return 0;
}
// g++ test.cpp
Read from std in and print
源自: https://www.geeksforgeeks.org/stdistream_iterator-stdostream_iterator-c-stl/
// Cpp program to illustrate
// Read a bunch of integers from the input stream
// and print them to output stream
#include <algorithm>
#include <iostream>
#include <iterator>
using namespace std;
int main()
{
// Get input stream and end of stream iterators
istream_iterator<int> cin_it(cin);
istream_iterator<int> eos;
// Get output stream iterators
ostream_iterator<int> cout_it(cout, " ");
// We have both input and output iterators, now we can treat them
// as containers. Using copy function we transfer data from one
// container to another.
// Copy elements from input to output using copy function
copy(cin_it, eos, cout_it);
return 0;
}
// g++ test.cpp
Read from file and sort
源自: https://www.geeksforgeeks.org/stdistream_iterator-stdostream_iterator-c-stl/
// Cpp program to illustrate
// Read a bunch of strings from a file
// sort them lexicographically and print them to output stream
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
using namespace std;
int main()
{
// Define a vector to store the strings received from input
vector < string > strings_v;
// Define the filestream object used to read data from file
ifstream fin("input_file.txt");
// Get input stream and end of stream iterators
istream_iterator < string > fin_it(fin);
istream_iterator < string > eos;
// Get output stream iterators
ostream_iterator < string > cout_it(cout, " ");
// Copy elements from input to vector using copy function
copy(fin_it, eos, back_inserter(strings_v));
// Sort the vector
sort(strings_v.begin(), strings_v.end());
// Copy elements from vector to output
copy(strings_v.begin(), strings_v.end(), cout_it);
return 0;
}
// g++ test.cpp
Contents of File "input_file.txt": quick brown fox jumps over the lazy dog Output: brown dog fox jumps lazy over quick the
Read from std in and sort
源自: https://www.geeksforgeeks.org/stdistream_iterator-stdostream_iterator-c-stl/
// Cpp program to illustrate
// Read a bunch of integers from the stream
// print the sorted order of even integers only
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
int main()
{
// Define a vector to store the even integers received from input
vector<int> vi;
// Get input stream and end of stream iterators
istream_iterator<int> cin_it(cin);
istream_iterator<int> eos;
// Get output stream iterators
ostream_iterator<int> cout_it(cout, " ");
// Copy even integer elements from input to vector using for_each function
for_each(cin_it, eos, [&](int a)
{
if (a % 2 == 0)
{
// if a is even push it to vector
vi.push_back(a);
}
});
// Sort the vector
sort(vi.begin(), vi.end());
// Copy elements from vector to output
copy(vi.begin(), vi.end(), cout_it);
return 0;
}
// g++ --std=c++11 test.cpp
使用下面的方式进行测试:
2
3
4
5
6
8
ctr+D // 表示EOF