# Stringstreams and escape characters

This topic is 1826 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm having some trouble with my .OBJ loader, when trying to load in the face data I'm not too sure on how to separate the numbers from the / for example:

string str;
getline(file, str);
stringstream ss(str);
string start;

ss >> start;

else if (start == "f") {
unsigned int x, y, z;
ss >> x >> y >> z

The X value reads fine.. but when it reads the next components it reads "\1" and "\2" etc. Is there any way to get around this?

Thanks

##### Share on other sites

You may want a string splitting function. This question on Stack Overflow should give you some ideas. I would suggest that you adapt this response to split based on a deliminator such as '/'. You would just convert the string to the correct type instead of returning a std::vector of strings. Or take the std::vector of strings and convert those as needed. You have options is all I'm saying.

##### Share on other sites

As you are discovering, std::streams aren't terribly useful for tokenizing strings. You are generally better off feeding the string into sscanf().

##### Share on other sites

As you are discovering, std::streams aren't terribly useful for tokenizing strings. You are generally better off feeding the string into sscanf().

Not true at all. And this is a trivial problem to solve...

int main() {
std::stringstream ss("f 3/1 4/2 5/3");
std::string type;
int xv, xn, yv, yn, zv, zn;
ss>>type;

std::cout<<"V: <"<<xv<<", "<<yv<<", "<<zv<<"> N: <"<<xn<<", "<<yn<<", "<<zn<<">"<<std::endl;
return 0;
}

In fact we can simplify that even more with a simple stream operator function, which gives us greater utility...
template<class E, class T>
std::basic_istream<E, T>& ignore(std::basic_istream<E, T>& stream) {
return stream.ignore();
}

int main() {
std::stringstream ss("f 3/1 4/2 5/3");
std::string type;

int xv, xn, yv, yn, zv, zn;

ss>>type;

ss>>xv>>ignore>>xn;
ss>>yv>>ignore>>yn;
ss>>zv>>ignore>>zn;

std::cout<<"V: <"<<xv<<", "<<yv<<", "<<zv<<"> N: <"<<xn<<", "<<yn<<", "<<zn<<">"<<std::endl;
return 0;
}
Which could be trivially expanded into an object with an overloaded extraction operator to handle even more cases (such as ignoring a longer number of characters, or ignoring specific types). Edited by Washu

##### Share on other sites

Not true at all. And this is a trivial problem to solve...

Perhaps I should have been more specific. Your solution also parses the expression "f 3 + 1 4 + 2 5 + 3", and the more insidious "f 3.1 4.2 5.3".

It isn't trivial to reproduce the validation implicit in sscanf(arg, "f %d/%d %d/%d %d/%d, &xv", &xn, &yv, &yn, &zv, &zn) using stringstreams.

Edit: though I suppose one could define a validating functor to use as a stream operator. Still, such a thing does not exist out of the box.

Edited by swiftcoder

##### Share on other sites

Thanks all for the replies! My trouble was for some reason last time when I did what Washu suggested I had problems where it was reading the string "\1" "\2" etc. But then I realised I was using an std::string and should use a char... Thanks for all the replies good info!

1. 1
2. 2
frob
15
3. 3
4. 4
Rutin
12
5. 5

• 12
• 12
• 58
• 14
• 15
• ### Forum Statistics

• Total Topics
632120
• Total Posts
3004219

×