0
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    ifstream fin("test.txt");

    vector<string> coll;

    typedef istreambuf_iterator<char> IStrBufIter;
    copy(IStrBufIter(fin), IStrBufIter(), back_inserter(coll)); // Error! Why?
}

The question is commented in the code.

The error I get is:

oi.cpp:15:62:   required from here
error: invalid user-defined conversion from ‘std::istreambuf_iterator<char, std::char_traits<char> >::char_type {aka char}’ to ‘std::vector<std::basic_string<char> >::const_reference {aka const std::basic_string<char>&}’ [-fpermissive]

The error messages that follow are too many to paste here. Please refer to the Error msg on gcc 4.7 http://pastebin.com/anKQqL00

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
xmllmx
  • 39,765
  • 26
  • 162
  • 323

2 Answers2

4

Consider what your copy is doing. It's repeatedly calling coll.push_back(someChar);

coll is a vector of strings. You are trying to push a char into it. You can't construct a string from a char.

Also, you should be using istream_iterator here, not istreambuf_iterator. You can either make coll a vector of chars, or if you are aiming to get each word in the file into your vector of strings (which I suspect you might be) you can change istream_iterator<char> to istream_iterator<string>.

Or, better yet, you can construct the vector in the first place using your iterators:

 vector<string> coll(istream_iterator<string>(fin), istream_iterator<string>());
David
  • 27,652
  • 18
  • 89
  • 138
3

If you want to put the contents of a file into a vector just loop through it.

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

int main()
{
    ifstream fin("test.txt");

    vector<string> coll;
    string str;
    while(getline(fin,str))
        coll.push_back(str);
}

Probably easier to deal with and self-explanatory.

Rapptz
  • 20,807
  • 5
  • 72
  • 86
  • However, I want to use std::copy here. Any idea? – xmllmx Feb 06 '13 at 02:26
  • @xmllmx This puts the _lines_ of the input into the vector. Is that what you want? – jogojapan Feb 06 '13 at 02:27
  • @xmllmx: If you want lines, you'll have to develop a special input iterator that reads a line at a time, or maybe you can find a public implementation of something like that. The standard library doesn't have one. – Benjamin Lindley Feb 06 '13 at 02:30
  • 1
    @BenjaminLindley wouldn't `istream_iterator` rather than `istreambuf_iterator` work instead? – Rapptz Feb 06 '13 at 02:30
  • 1
    @Rapptz: Not for getting lines. `istream_iterator` uses `operator>>`, and with strings, that means reading whitespace delimited tokens. Any whitespace, not just newlines. – Benjamin Lindley Feb 06 '13 at 02:31
  • @xmllmx why do you *want* to use `std::copy`? It's much easier to use this approach for what you're doing. – Rapptz Feb 06 '13 at 02:34
  • 1
    Another option would be defining a special type that encapsulates a string, and has an implicit conversion to `std::string`, but its overload of `operator>>` reads in a whole line instead of just a word. Then you could use `istream_iterator`. That would probably be simpler than implementing an iterator, but less interesting and less useful. – Benjamin Lindley Feb 06 '13 at 02:35