On 2005-12-16, George <ge**********@excite.com> wrote:
Hi All,
I'm trying to learn c++/stl. I'd like a fancy way to read
lines of an ascii file into vector of stringbufs. I made a
first attempt, but the compiler complains about private
constructors in streambuf.
I'd like to use algorithms instead of a loop, but I don't know
if that is possible. Any ideas? Thanks in advance.
Here's a program closely modeled on yours, using std::string
instead of std::stringbuf, and std::copy.
#include <fstream>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
int main()
{
std::vector<std::string> v;
std::ifstream f(__FILE__);
std::cout << __FILE__ << '\n';
std::istream_iterator<std::string> start(f), finish;
std::copy(start, finish, std::back_inserter(v));
std::cout << v.size() << '\n';
return 0;
}
You don't need to use stringbuf to use istream_iterator. Perhaps
you needed it for something else.
You can pass the filename to the constructor of the file streams.
If the file is not found, an exception will be thrown.
Check out back_inserter, and some of the other adaptors.
You normally don't want to insert into a vector, unless it's at
the end iterator. A back_inserter calls push_back, which is the
most efficient way to build up a vector.
There are other ways to count the strings in a file that won't
need to build up a vector. Here's one:
#include <fstream>
#include <string>
#include <algorithm>
#include <functional>
template <typename T>
struct yes: std::unary_function<T, bool>
{
bool operator()(const T&) const { return true; }
};
int main()
{
std::ifstream f(__FILE__);
std::cout << __FILE__ << '\n';
std::istream_iterator<std::string> start(f), finish;
std::cout << std::count_if(start, finish, yes<std::string>()) << '\n';
return 0;
}
You could also write your own stateful functor and use
std::for_each. I believe the standard doesn't actually bless this
practice... yet. The problem is that implementations aren't
prohibited form copying your functor. In practice, you're very
unlikely to face problems.
--
Neil Cerutti