拆分字符串的问题

时间:2010-07-05 07:48:57

标签: c++

有人可以告诉我这段代码的问题。我正在使用getline函数读取每一行,并再次使用相同的函数来分割:分隔符的字符串。

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

错误消息是:

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' 

4 个答案:

答案 0 :(得分:4)

使用char delim = ':';,我还建议您使用istringstream代替stringstream。此外,循环错误:

#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();

另请注意,tokens将在每一行重置。如果您打算在行之间累积tokens,请在外部循环之前声明它。

答案 1 :(得分:2)

这段代码汇编得很好:

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

答案 2 :(得分:0)

您只读到第一个delim发生的文件的每一行 - 而不是完整的行。见http://www.cplusplus.com/reference/iostream/istream/getline/

  

提取字符直到   (n - 1)个字符已被提取   或找到分隔字符   (如果此参数为,则为delim   指定的,或'\ n'另外指定),或'\ n'否则)

答案 3 :(得分:0)

我倾向于使用迭代器接口来包装std :: getline以便它 与其他基于迭代的算法很好地配合。这是 这是一个简单的方法。

    /** 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;

    };