Reputation: 13474
I am trying to understand sscanf
behaviour for that I have executed below two program.
void main()
{
char *a = "225.311";
int x = 0, y = 0;
sscanf(a, "%d.3%d", &x, &y);
printf("x is %d, y is %d\n", x, y);
}
output is
x is 255, y is 11
Below program is not working as per my expectation.
void main()
{
char *a = "225.311";
int x = 0, y = 0;
sscanf(a, "%d5.3%d", &x, &y);
printf("x is %d, y is %d\n", x, y);
}
I am expecting 25,11
, but the output is
x is 255, y is 0
I am expecting sscanf
behaviour should exact same as sprintf in reverse manner. But its not working in my second program. If the format specifed is %d5.3%d
, then it has to consider 5
as delimeter. But its not considering and reading all digits for x
, and then dot is not matching with 5.3%d
so it quits there.
Can somebody please explain this.
Upvotes: 0
Views: 120
Reputation: 154218
Suggest using a different format and checking the results of sscanf()
. Also to distinguish fractions like "0.001" and "0.1", note positions.
const char *a = "225.0311";
int ipart = 0;
unsigned fractionpart;
int n1, n2;
if (sscanf(a, "%d.%n%u%n", &ipart, &n1, &fractionpart, &n2) != 2) {
Handle_BadInput();
}
printf("ipart is %d, fractionpart is %0*u\n", ipart, n2 - n1, fractionpart);
// ipart is 225, fractionpart is 0311
As @ajay discusses, "%d5.3%d"
looks for an int
, then "5.3"
then another int
.
Upvotes: 1
Reputation: 9680
That's because the %d
conversion specifier means sscanf
will keep reading from the buffer pointed to by a
till it encounters a non-numeric character in the buffer. This means that %d
will consume up till 225
in the string literal "225.311"
in your second example.
If the format specifed is
%d5.3%d
, then it has to consider 5 as delimeter.
No, that's not true. 5
in the format string means sscanf
will match it exactly (after reading an int) in the buffer it reads from. If it fails to match it, then sscanf
will return and the value of y
is left unchanged. You can check for this by storing the result of sscanf
. The return value is equal to the number of input items successfully matched and assigned.
char *a = "225.311";
int x = 0, y = 0;
int retval = sscanf(a, "%d5.3%d", &x, &y);
printf("%d\n", retval); // prints 1
However, note that if the sequence of numeric characters in the buffer is too long to fit into an int
, then the behaviour is undefined because of signed integer overflow.
Upvotes: 4