views:

162

answers:

4

So that you could do something like this, for instance:

std::string a("01:22:42.18");
std::stringstream ss(a);
int h, m, s, f;
ss >> h >> m >> s >> f;

Which normally requires the string to be formatted "01 22 42 18". Can you modify the current locale directly to do this?

+2  A: 

Take a look at scanf and fscanf. You might* be able to do something like this:

int h, m, s, f;
sscanf(a.c_str(), "%d:%d:%d.%d", &h, &m, &s, &f);

* Caveat: It's been a while for me and C++

Justin Johnson
ephemient
Thanks, that's a practical solution.
henle
@ephemient Ya, that's the one. Like I said, it's been a while since I've touched any C/C++ @henle If that's your solution, then mark it as the answer mate ;)
Justin Johnson
Ok, Justin, since you're asking nicely, but the other suggestions were good as well! ;)
henle
+2  A: 
char c;
if (!(ss >> h >> c) || c != ':') return;
if (!(ss >> m >> c) || c != ':') return;
if (!(ss >> s >> c) || c != '.') return;
if (!(ss >> f) || ss >> c) return;
ephemient
+5  A: 

I don't think you can change the default delimiter without creating a new locale, but that seems hackish. What you can use do is use getline with a third parameter specifying the delimiter character or you could read the delimiters and not do anything with them (e.g. ss >> h >> d >> m >> d >> s >> d >> f).

You could also write your own parsing class that handles splitting strings for you. Or better yet, use boost::split from Boost's String Algorithms Library.

Firas Assaad
the annoying thing with `boost::split` and `getline` is that you have to split up the strings and then feed them back into a stream to get the integers
henle
You can use `boost::split` to transform the `std::string` into a `std::vector<std::string>`, then use `std::transform` with `boost::lexical_cast` to transform the `std::vector<std::string>` into a `std::vector<unsigned int>`
James McNellis
+3  A: 

You can do this by creating a locale with a ctype facet classifying : as whitespace.

Jerry Coffin explains how you can specify whitespace characters in this answer to another question.

James McNellis
Thank you, that would be the literal answer to my question! Though I'm trying to figure out if you can just do anrc[':'] = std::ctype_base::space;without creating a whole new locale ...
henle
Unfortunately, since ios_base classifies characters as whitespace based on the imbued locale, I don't think there are any other options. Firas's suggestion of boost::split (or, alternatively, boost::tokenizer) is probably your next best bet.
James McNellis