problem splitting a string
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;
};
精彩评论