开发者

problem splitting a string

开发者 https://www.devze.com 2023-01-05 13:10 出处:网络
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.

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_istrea开发者_StackOverflowm<_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' 


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.


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;
}


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)


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;

    };
0

精彩评论

暂无评论...
验证码 换一张
取 消