Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sscanf c++ splitting string to ints sometimes doesn't work

I am writing a program that converts a date string to three separate int variables: year, month, day.

int m,d,y;
sscanf("2011-03-08","%i %*[-] %i %*[-] %i",&y,&m,&d);
cout << y<<" "<<m<<" "<<" "<<d<<std::endl;
sscanf("2011-03-07","%i %*[-] %i %*[-] %i",&y,&m,&d);
cout << y<<" "<<m<<" "<<" "<<d;

If I convert 2011-03-08 or 2011-03-09, the day will be 0, but for 2011-03-07,06,... the day is 7,6,... as i would expect. Could somebody explain it, why doesn't it work for 08 or 09 and only for them?

Thank you in advance!

like image 973
Fekete Ferenc Avatar asked Feb 18 '23 10:02

Fekete Ferenc


2 Answers

See sscanf

i
Matches an optionally signed integer; the next pointer must be a pointer to int. The integer is read in base 16 if it begins with 0x or 0X, in base 8 if it begins with 0, and in base 10 otherwise. Only characters that correspond to the base are used.

08 will be scanned as an octal integer, because it starts with 0. But 08 is not a valid octal integer, whereas 07 is. If you use %d instead of %i, it will work as you expect.

sscanf("2011-03-08","%d %*[-] %d %*[-] %d", &y, &m, &d);

or even simpler

sscanf("2011-03-08","%d-%d-%d", &y, &m, &d);

Depending on what you want to do with the result, you may also consider strptime

strptime - convert a string representation of time to a time tm structure

struct tm t;
strptime("2011-03-08, "%Y-%m-%d", &t);
like image 176
Olaf Dietsche Avatar answered Feb 20 '23 20:02

Olaf Dietsche


The problem is that %i treats 08 as an octal integer, so possible solution could be to use %d instead, but since this is C++, you should use std::istringstream (#include <sstream>) instead:

int y,m,d;
char delimiter;

std::istringstream dateStream("2011-03-08");
dateStream >> y >> delimiter >> m >> delimiter >> d;

std::cout << y << " " << m << " " << d;
like image 45
LihO Avatar answered Feb 20 '23 21:02

LihO