Fekete Ferenc
Fekete Ferenc

Reputation: 119

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!

Upvotes: 4

Views: 1082

Answers (3)

Olaf Dietsche
Olaf Dietsche

Reputation: 74028

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);

Upvotes: 5

LihO
LihO

Reputation: 42083

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;

Upvotes: 2

Anonymouse
Anonymouse

Reputation: 945

Your format string is wrong... it should simply be "%4d-%02d-%02d"

It wouldn't hurt to check that the sscanf worked too with if (3 != sscanf(...)) { /* failed */ }

Upvotes: 1

Related Questions