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 unsigned
s 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