Re: How to read a for-digits number with I/O operators ?
On 8=E6=9C=8812=E6=97=A5, =E4=B8=8B=E5=8D=8811=E6=99=8219=E5=88=86, Timothy=
Madden <terminato...@gmail.com> wrote:
Francesco S. Carta wrote:
Timothy Madden <terminato...@gmail.com>, on 12/08/2010 16:38:34, wrote:
Hello
My application connects to a server that sends back a date in
"YYYYMMDDhhmmss" format, that is a date like "20100803102438".
How can I read the year, month, day, hour, minute and second from this
string with standard stream classes ? To get the time_t ?
Get a char at a time (or find an appropriate member that reads n chars)
in order to separate the various values as different strings, then
extract the actual values from these strings (either using the extracto=
r
operator on a stringstream or by passing a C-string to the appropriate =
C
function [*] that read ints from a C-string).
About time_t, look up its specs and see how to build it using the value=
s
that you just extracted from that server string using some variant of
the method delineated above.
Getting the time_t is just a matter of filling one struct tm variable
with the components and calling mktime().
atoi()/atol() have the problem that they silently stop if the string
contains characters other than digits; I was hoping for a method that
would also check the format (or skip non-digits instead of stopping). I
had to do something like
string strDate = "20100803102438";
string::const_iterator
it = strDate.begin();
istringstream
stream;
stream.exceptions(stream.badbit | stream.failbit);
stream.str(string(it, it += 4));
stream >> year;
stream.str(string(it, it += 2));
stream >> month;
stream.str(string(it, it += 2));
stream >> day;
//...
//...
However I think this does not check for non-digits and I think scanf can
do the job in just one call.
Thank you,
Timothy Madden
Here is the basic one. You can modify it or add various checking.
--------------------------------------
#include <iostream>
inline int charnum(char ch)
{ return ch-'0'; };
static int parse_pnum(const char* str, size_t len)
{
int sum=0;
for(const char *p=str, *end=str+len; p!=end; ++p) {
int d=charnum(*p);
if((d<0)||(d>9)) {
throw "Invalid digit in " __FILE__;
}
sum*=10;
sum+=d;
}
return sum;
};
int main(int,char*[])
try {
const char str[]="20100803102438";
std::cout << "year = " << parse_pnum(str ,4) << '\n'
<< "month = " << parse_pnum(str+4 ,2) << '\n'
<< "mday = " << parse_pnum(str+6 ,2) << '\n'
<< "hour = " << parse_pnum(str+8 ,2) << '\n'
<< "minute= " << parse_pnum(str+10,2) << '\n'
<< "second= " << parse_pnum(str+12,2) << '\n'
<< '\n';
return 0;
}
catch(...) {
std::cerr << "unknown throw object\n";
throw;
};