advertisement
Login | Register   
  Include Code  Search Tips
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Stream iterators, as you have seen, can automate and simplify I/O immensely. However, this feature isn't widely used as one would expect. Do you think the culprit is in the sophisticated design itself, which perhaps deters beginners or is it only because this feature hasn't been publicized enough? Let us know what you think in our C++ Dicussion Forum.
Partners & Affiliates
advertisement
advertisement
advertisement
advertisement
Average Rating: 3.3/5 | Rate this item | 3 users have rated this item.
Streamline Your Bulk I/O Operations with Stream Iterators (cont'd)
Dumping a Container
"GUI-based applications rarely use cin and cout, so what's the big deal?" you're probably asking. To demonstrate the powerfulness of stream iterators, I'll show you now a more realistic example that uses stream iterators to write the contents of a container to cout, and then to a file:

void func()
{
vector<int> vi(10,35); //fill with 10 int of the value 35
//write contents of vi to cout, each number on a new line
std::copy(vi.begin(),
vi.end(),
ostream_iterator<int> (cout, "\n"));
}
advertisement
func() uses the copy() algorithm to write the vector's elements to cout. The first two copy() arguments are iterators that mark the boundaries of the input sequence. Here's the output of this function:

Figure 4. Here's the output of the func() function.

Writing a container's elements to a file is similar:


void f(const vector<int> &vi)
{
//open a file in write mode
ofstream vi_dump("vi.txt");
if (!vi_dump) //failure?
{
cerr<<"couldn't open file";
exit(1);
}
copy(vi.begin(),
vi.end(),
ostream_iterator<int> (vi_dump, " "));
}
The third copy() argument is an ostream_iterator bound to a file stream. copy() therefore writes vi's content to the file vi.txt.

Writing a Stream to a Container
Reading a file into a container is just as easy:


#include<vector>
#include<fstream>
#include<algorithm>
#include<cstdlib>
#include<iostream>
using namespace std;
int main()
{
vector<int> vi;//vector to be filled
ifstream vi_dump("vi.txt"); //open for read
if (!vi_dump)
{
cerr<<"couldn't open file";
exit(1);
}
copy(istream_iterator<int> (vi_dump),
istream_iterator<int> (),
back_inserter(vi));
}
copy() writes the file's content into vi. back_inserter(vi) returns a special output iterator that automatically causes vi to allocate storage for incoming data as needed.

Iterators Reiterated
If you haven't used stream iterators before, this technique might look like witchcraft. However, it's based on a recurrent pattern:

  1. Treat data sources as input streams and targets as output streams.
  2. Create iterators that point to these streams.
  3. Use an algorithm or a container to transfer data from a source to a target.
For the sake of simplicity, my examples use copy() exclusively. However, you can easily use this technique with other algorithms, such as transform(), find(), replace() etc.
Previous Page: Demonstrating the Problem  
Danny Kalev is a system analyst and software engineer with 13 years of experience, specializing in C++ and object-oriented analysis and design. He is a member of the ANSI C++ standardization committee and the author of ANSI/ISO C++ Professional Programmer's Handbook (Que, 1999, ISBN: 0789720221). Reach him at dannykk@inter.net.il.
Page 1: IntroductionPage 3: Dumping a Container
Page 2: Demonstrating the Problem 
Please rate this item (5=best)
 1  2  3  4  5
advertisement