问题
My code is posted below. I want to be able to parse using the delimiters " ()," and convert the strings into integers in cpp.
while(getline(fin, line))
{
x = atoi((strtok(line.c_str(),'(,)'));
xx = atoi((strtok(NULL,"(),"));
xxx = atoi((strtok(NULL,"(),")));
cout << x << " " << xx << " " << xxx << "\n";
}
but for some reason I get the following errors
GraphTest.cpp:134: error: invalid conversion from ‘const char*’ to ‘char*’
GraphTest.cpp:134: error: initializing argument 1 of ‘char* strtok(char*, const char*)’
The .c_str should convert my string into a c type string allowing me to use the atoi and strtok functions. I am very confused and would appreciate any help.
回答1:
I had a similar problem with needing to parse with multiple delimiters and could not find a good solution anywhere so I ended up just making a function.
string getlineMultDelimiter(istream &is, string dlm, bool includeDelimiter)
{
string str;
char c;
bool found = false;
while (!found && is)
{
for (size_t i = 0; i < dlm.length() && !found; ++i)
found = dlm[i] == is.peek();
if (!found || includeDelimiter)
{
is.get(c);
str += c;
}
}
return str;
}
It will use all chars in the dlm string as a delimiter and you can choose whether to include the delimiter or not in the returned string.
回答2:
It doesn't compile because c_str()
returns a const char*
, it's supposed to be a constant pointer to not modifiable internal string
buffer. On the other hand strtok()
accepts a char*
because it modifies its input string.
Now you have two options: get a C string usable from strtok()
or rewrite everything to be C++.
Create a new modifiable C string from your C++ string:
char* modifiableLine = strdup(line.c_str());
x = atoi((strtok(modifiableLine, "(,)"));
// Other processing
free(modifiableLine);
You can do it if you have to keep a big amount of C code wrapped inside a C++ function/class. A better solution is to use what C++ Standard Library offers (also dropping atoi()
C function if C++ 11). Let's first write an helper function:
int readNextInt(istringstream& is, const string& delimiters) {
string token;
if (getline(is, token, delimiters))
return stoi(token);
return 0; // End of stream?
}
Used like this:
istringstream is(line)
x = readNextInt(is, "(),");
xx = readNextInt(is, "(),");
xxx = readNextInt(is, "(),");
Please note that standard C++ function getline()
doesn't accept a string
for delimiters parameter but a single char
only then you have to write your own overloaded version. Take a look to this post for good and nice possible implementation (you may also simply replace getline()
with is >> token
after is.imbue()
, see given example).
Well...if you're already using Boost then you may simply use boost::tokenizer
.
来源:https://stackoverflow.com/questions/27249617/i-am-very-confused-on-how-to-parse-multiple-delimiters-using-getline-and-strtok