I would like to use the facilities provided by stringstream to extract values from a fixed-format string as a type-safe alternative to sscanf. How can I do this?
Consider the following specific use case. I have a std::string in the following fixed format:
YYYYMMDDHHMMSSmmm
Where:
YYYY = 4 digits representing the year
MM = 2 digits representing the month ('0' padded to 2 characters)
DD = 2 digits representing the day ('0' padded to 2 characters)
HH = 2 digits representing the hour ('0' padded to 2 characters)
MM = 2 digits representing the minute ('0' padded to 2 characters)
SS = 2 digits representing the second ('0' padded to 2 characters)
mmm = 3 digits representing the milliseconds ('0' padded to 3 characters)
Previously I was doing something along these lines:
string s = "20101220110651184";
unsigned year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, milli = 0;
sscanf(s.c_str(), "%4u%2u%2u%2u%2u%2u%3u", &year, &month, &day, &hour, &minute, &second, &milli );
The width values are magic numbers, and that's ok. I'd like to use streams to extract these values and convert them to unsigneds in the interest of type safety. But when I try this:
stringstream ss;
ss << "20101220110651184";
ss >> setw(4) >> year;
year retains the value 0. It should be 2010.
How do I do what I'm trying to do? I can't use Boost or any other 3rd party library, nor can I use C++0x.
Erm, if it's fixed format, why don't you do this?
std::string sd("20101220110651184");
// insert spaces from the back
sd.insert(14, 1, ' ');
sd.insert(12, 1, ' ');
sd.insert(10, 1, ' ');
sd.insert(8, 1, ' ');
sd.insert(6, 1, ' ');
sd.insert(4, 1, ' ');
int year, month, day, hour, min, sec, ms;
std::istringstream str(sd);
str >> year >> month >> day >> hour >> min >> sec >> ms;
One not particularly efficient option would be to construct some temporary strings and use a lexical cast:
std::string s("20101220110651184");
int year = lexical_cast<int>(s.substr(0, 4));
// etc.
lexical_cast can be implemented in just a few lines of code; Herb Sutter presented the bare minimum in his article, "The String Formatters of Manor Farm."
It's not exactly what you're looking for, but it's a type-safe way to extract fixed-width fields from a string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With