sscanf problem

J

jacob navia

Consider this program:
// ScanTest.c
#include <stdio.h>
int main(int argc, char* argv[])
{
int x1, x2, x3;
char s[16] = "38 02 14";
char t[16] = "38 08 14";
sscanf( t, "%i %i %i", &x1, &x2, &x3 );
printf( "x1 = %i, x2 = %i, x3 = %i\n", x1, x2, x3 );

sscanf( s, "%i %i %i", &x1, &x2, &x3 );
printf( "x1 = %i, x2 = %i, x3 = %i\n", x1, x2, x3 );
return 0;
}

The output using lcc-win32 sscanf is:
x1 = 38, x2 = 8, x3 = 14
x1 = 38, x2 = 2, x3 = 14

The output with gcc (under linux) or with Microsoft VC6++ is:
x1 = 38, x2 = 0, x3 = 8
x1 = 38, x2 = 2, x3 = 14

I can see why this should be. Can anyone here explain?

Thanks for your time

P.S. I have verified that there is no uppercase "O" that replaces
a zero. The "08" is well zero and then eight.

Why does it stop???
 
J

jacob navia

Forget it. I found the problem...

The string 08 should be interpreted as an octal number since it begins with
zero
 
M

Michael Hoffman

The output using lcc-win32 sscanf is:
x1 = 38, x2 = 8, x3 = 14
x1 = 38, x2 = 2, x3 = 14

The output with gcc (under linux) or with Microsoft VC6++ is:
x1 = 38, x2 = 0, x3 = 8
x1 = 38, x2 = 2, x3 = 14

My Linux man page for sscanf says that %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."

02 = octal 2 = 2
08 = octal 8??? = makes no sense
 
E

Emmanuel Delahaye

jacob navia said:
Consider this program:
// ScanTest.c
#include <stdio.h>
int main(int argc, char* argv[])
{
int x1, x2, x3;
char s[16] = "38 02 14";
char t[16] = "38 08 14";
sscanf( t, "%i %i %i", &x1, &x2, &x3 );

"08" is an invalid octal representation. You should use "%d" and instead of
"%i" if it the string is supposed to be a decimal representation of the value
8.

Keep in mind that %i with scanf() acts like strtol() with base 0. It tries to
perform an automatic conversion assumed on the value of the first characters:

0x[0-9,a-f,A-F[*]] -> hexacecimal
0[0-7[*]] -> octal
[+-]1-9[0-9[*]] -> decimal
 
D

Dan Pop

In said:
Forget it. I found the problem...

The string 08 should be interpreted as an octal number since it begins with
zero

Which means that the conversion stops when the 8 is encountered.

I've never understood the rationale for having %i. It's far more
confusing than useful and it was not mentioned in K&R1. Did it already
exist in the pre-ANSI days or is it a committee invention?

Anyway, if you don't use it, it's as good as if it didn't exist. Unless
you're an implementor: you still have to get it right, of course.

Dan
 
M

Martin Ambuhl

jacob said:
Consider this program:
// ScanTest.c
#include <stdio.h>
int main(int argc, char* argv[])
{
int x1, x2, x3;
char s[16] = "38 02 14";
char t[16] = "38 08 14";
sscanf( t, "%i %i %i", &x1, &x2, &x3 );
printf( "x1 = %i, x2 = %i, x3 = %i\n", x1, x2, x3 );

sscanf( s, "%i %i %i", &x1, &x2, &x3 );
printf( "x1 = %i, x2 = %i, x3 = %i\n", x1, x2, x3 );
return 0;
}

The output using lcc-win32 sscanf is:
x1 = 38, x2 = 8, x3 = 14
x1 = 38, x2 = 2, x3 = 14

The output with gcc (under linux) or with Microsoft VC6++ is:
x1 = 38, x2 = 0, x3 = 8
x1 = 38, x2 = 2, x3 = 14

I can see why this should be. Can anyone here explain?

Because lcc's library function scanf is broken. '%i' specifies that the
argument be interpreted as by strtol with a value of 0 for the base.
'08' is interpreted as octal '0' followed by decimal '8'.
 
J

jacob navia

Because lcc's library function scanf is broken.

WAS broken.

It is fixed now. What a pain this subtle differences between %i and %d

thanks for your time
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top