1

Can some one please tell me the problem with this code. I am reading each line using getline function and again using the same function for splitting the string for : delimiter.

 string line,item;
 ifstream myfile("hello.txt");

 if(myfile.is_open()) {
   string delim =":";
   while(!myfile.eof()) {
     vector<string> tokens;
     getline(myfile,line);
     stringstream iss(line);

     while(getline(iss,item,delim)) {
       tokens.push_back(item);
    }
  }

  myfile.close();
}

The error message is:

C2780: 'std::basic_istream<_Elem,_Traits> &std::getline(std::basic_istream<_Elem,_Traits> &,std::basic_string<_Elem,_Traits,_Alloc> &)' : expects 2 arguments - 3 provided 1> c:\program files\microsoft visual studio 8\vc\include\string(528) : see declaration of 'std::getline' 
13
  • also can someone format the code pls. I am unable to do it. Commented Jul 5, 2010 at 7:50
  • The formatter can get confused if you start with code. I moved your question in front of the code. Commented Jul 5, 2010 at 7:55
  • @mousey: Never mix tabs with spaces to indent source code. I prefer spaces (because the formatting will appear the same in virtually all editors -- and in a shell). A good IDE will have tab/space settings. Commented Jul 5, 2010 at 7:57
  • @mousey: Also, pasting the exact error message will help. Commented Jul 5, 2010 at 7:59
  • Can you also provide sample input & output for your code? Commented Jul 5, 2010 at 8:00

4 Answers 4

4

Use char delim = ':'; and I also suggest using istringstream instead of stringstream. Also, the loop is wrong:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
...
  char delim = ':';
  while (std::getline(myfile,line))
  {
    vector<string> tokens;
    istringstream iss(line);

    while(std::getline(iss,item,delim))
    {
        tokens.push_back(item);
    }
  }
  myfile.close();

Also, note that tokens will get reset on each line. If you intend to accumulate tokens across lines, declare it before the outer loop.

Sign up to request clarification or add additional context in comments.

2 Comments

I've amended the answer to indicate the headers you need. Do you have all those?
I am using #include <iostream> #include <fstream> #include <string> #include <sstream> #include <algorithm> #include <iterator> #include <vector>
2

This code compiles well:

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <vector>

using namespace std;

int main(int argc, char **argv)
{
    string line,item;
    ifstream myfile("hello.txt");

    if(myfile.is_open()) {
        char delim =':'; // use char instead of string as Marcelo Cantos said
        while(!myfile.eof()) {
            vector<string> tokens;
            getline(myfile,line);
            stringstream iss(line);

            while(getline(iss,item,delim)) {
                tokens.push_back(item);
            }
        }
    }

    myfile.close();
    return 0;
}

3 Comments

You should not use oef() as predicate in the while loop. Better would be to call getline() there.
@rubenvb can you please explain why I shouldnt use eof() ?
See cplusplus.com/doc/tutorial/files under the section "checking state flags": eg when a stream goes into fail state, a next extraction will work on the same byte sequence. Moreso, see eg mathbits.com/mathbits/compsci/Files/End.htm that also recommends using getline instead of eof(). When a read fails for another reason than eof reached, you miss the error. In most cases, it also allows for shorter code :). As an additional reference (although it is C, the same happens for C++ streams):drpaulcarter.com/cs/common-c-errors.php#4.2
0

You read each line of the file just until the first delim occures - not the complete line. See http://www.cplusplus.com/reference/iostream/istream/getline/:

Characters are extracted until either (n - 1) characters have been extracted or the delimiting character is found (which is delim if this parameter is specified, or '\n' otherwise)specified, or '\n' otherwise)

4 Comments

yes I am reading a line and then using that line to split it. But my code is not working. Its giving me a syntax error!
getline(myfile,line) in his code does read the complete line. He then stuffs it into a stringstream, and reads until delimiter from that. It's not clear which of those you're referring to (if any).
@TheJuice error C2780: 'std::basic_istream<_Elem,_Traits> &std::getline(std::basic_istream<_Elem,_Traits> &,std::basic_string<_Elem,_Traits,_Alloc> &)' : expects 2 arguments - 3 provided error C2784: 'std::basic_istream<_Elem,_Traits> &std::getline(std::basic_istream<_Elem,_Traits> &,std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem)' : could not deduce template argument for 'std::basic_istream<_Elem,_Traits> &' from 'std::istringstream' 1> c:\program files\microsoft visual studio 8\vc\include\string(476) : see declaration of 'std::getline'
you are describing std::istream::getline. @mousey is using std::getline from <string>.
0

I tend to prefer to wrap std::getline with an iterator interface so that it plays nicely with other iteration based algorithms. Here is an easy way to do this.

    /** Proxy class to help the LineStreamIterator 
     * consume lines.
     */
    class LineString {
        std::string buffer;
    public:
        friend std::istream & operator>>(std::istream &is, LineString &li) {
            std::getline(is, li.buffer);
            return is;
        }
        friend std::ostream & operator<<(std::ostream &os, const LineString &li){
            os << li.buffer;
            return os;
        }

        operator std::string () const { return buffer; }
    };

    /**  Base class of the LineIterator */
    typedef std::istream_iterator<LineString> LineIteratorBase;

    /** An input iterator that yields lines from the
     * istream it is constructed with.
     * @code
     *  LineIterator it(cin);
     *  for (; it !=LineIterator(); ++it){
     *      std::cout << *it << " --- " << std::endl;
     *  }
     * @endcode
     */
    class LineIterator : public LineIteratorBase {
    public:
        LineIterator() : LineIteratorBase()
        {}

        LineIterator(std::istream & is): LineIteratorBase(is)
        {}

        /** Implement the dereference so that a string is
         * returned
         */
        const std::string operator * (){
            return (std::string) this->LineIteratorBase::operator *(); 
        }

        /**  value_type trait */
        typedef std::string                value_type;

        /**  pointer type trait */
        typedef std::string*               pointer;

        /**  reference type trait */
        typedef std::string&               reference;

    };

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.