help to explain sscanf()

B

BlueJ

Hi,

I run the following source code:

#include <stdio.h>

main()
{
int i;
unsigned int j;
char input[] = "10 0x1b aaaaaaaa bbbbbbb";
char s[5];
sscanf(input, "%d %x %5[a-z] %*s %f ", &i, &j, s, s);
printf("%d %d %s\n", i, j, s);
}


And it prints out: 10 27 aaaaa

What I understand is sscan puts something into s twice. the first
time, s = "aaaaa". afterwards, sscanf put some floating number to s.
So when printf, s should be not aaaa.

can anybody help to explain?
 
M

Mark Bluemel

BlueJ said:
Hi,

I run the following source code:

#include <stdio.h>

main()
{
int i;
unsigned int j;
char input[] = "10 0x1b aaaaaaaa bbbbbbb";
char s[5];
sscanf(input, "%d %x %5[a-z] %*s %f ", &i, &j, s, s);
printf("%d %d %s\n", i, j, s);
}


And it prints out: 10 27 aaaaa

What I understand is sscan puts something into s twice.

Does it? Are you sure?
> the first
time, s = "aaaaa". afterwards, sscanf put some floating number to s.


So when printf, s should be not aaaa.

can anybody help to explain?
Read the documentation for scanf - what does the return value tell you?
 
B

Barry Schwarz

Hi,

I run the following source code:

#include <stdio.h>

main()
{
int i;
unsigned int j;
char input[] = "10 0x1b aaaaaaaa bbbbbbb";
char s[5];
sscanf(input, "%d %x %5[a-z] %*s %f ", &i, &j, s, s);

What exactly do you think a conversion specification means %5[a-z]
means? Did you perhaps want the two specifications to read %5[a-z]s
%*s instead of %5[a-z] %*s, a single specification which has two %
characters and an imbedded space?

Which argument corresponds to the %f? Does it in fact point to a
float?
printf("%d %d %s\n", i, j, s);

What type of argument does the second %d require? What type did you
give it?
}


And it prints out: 10 27 aaaaa

What I understand is sscan puts something into s twice. the first
time, s = "aaaaa". afterwards, sscanf put some floating number to s.

What type is s? Is it capable of holding a float?
So when printf, s should be not aaaa.

can anybody help to explain?

By definition, undefined behavior is unexplainable.


Remove del for email
 
B

Ben Bacarisse

Barry Schwarz said:
I run the following source code:

#include <stdio.h>

main()
{
int i;
unsigned int j;
char input[] = "10 0x1b aaaaaaaa bbbbbbb";
char s[5];
sscanf(input, "%d %x %5[a-z] %*s %f ", &i, &j, s, s);

What exactly do you think a conversion specification means %5[a-z]
means? Did you perhaps want the two specifications to read %5[a-z]s
%*s instead of %5[a-z] %*s, a single specification which has two %
characters and an imbedded space?

A %[ format ends at "the matching ]" which is the first ] unless the
format starts [] or [^]. The original %5[a-z] is quite probably
right.

As you point out, the 's' argument supplied for the %f is wrong.
 
B

Barry Schwarz

Barry Schwarz said:
I run the following source code:

#include <stdio.h>

main()
{
int i;
unsigned int j;
char input[] = "10 0x1b aaaaaaaa bbbbbbb";
char s[5];
sscanf(input, "%d %x %5[a-z] %*s %f ", &i, &j, s, s);

What exactly do you think a conversion specification means %5[a-z]
means? Did you perhaps want the two specifications to read %5[a-z]s
%*s instead of %5[a-z] %*s, a single specification which has two %
characters and an imbedded space?

A %[ format ends at "the matching ]" which is the first ] unless the
format starts [] or [^]. The original %5[a-z] is quite probably
right.

Yes. For some reason I had it in my mind that the [...] was a
modifier when it is actually a specification. Oddly enough, n1124
says the - makes the behavior implementation defined. I wonder if any
system (other than the DS9000) does something different from the
obvious.


Remove del for email
 
B

Ben Pfaff

Barry Schwarz said:
sscanf(input, "%d %x %5[a-z] %*s %f ", &i, &j, s, s);
Oddly enough, n1124 says the - makes the behavior
implementation defined. I wonder if any system (other than the
DS9000) does something different from the obvious.

It's probably implementation-defined because the characters in
between 'a' and 'z' are implementation-defined; 'a' might not
even precede 'z'. Only ranges of digits could be portable.
 
B

Ben Bacarisse

Ben Pfaff said:
Barry Schwarz said:
sscanf(input, "%d %x %5[a-z] %*s %f ", &i, &j, s, s);
Oddly enough, n1124 says the - makes the behavior
implementation defined. I wonder if any system (other than the
DS9000) does something different from the obvious.

It's probably implementation-defined because the characters in
between 'a' and 'z' are implementation-defined; 'a' might not
even precede 'z'. Only ranges of digits could be portable.

I think Barry Schwarz may be commenting on the extreme degree of
latitude given. The text says:

"If a - character is in the scanlist and is not the first, nor the
second where the first character is a ^, nor the last character,
the behavior is implementation-defined."

So on a DS9000, %[a-z] can match digit sequences and %[z-a] can match
UK postcodes. Equally, %[0-9] need not match digits given that
definition (provided the implementation does say what it means).

It would have been more helpful to insist that <x>-<y> denotes a range
(from x to y) of characters determined by the implementation's
character set (provided y >= x). Then %[0-9] would then be portable,
and %[a-z] would mean the same on all implementations that use the same
character set.
 
C

Charlie Gordon

Ben Pfaff said:
Barry Schwarz said:
sscanf(input, "%d %x %5[a-z] %*s %f ", &i, &j, s, s);
Oddly enough, n1124 says the - makes the behavior
implementation defined. I wonder if any system (other than the
DS9000) does something different from the obvious.

It's probably implementation-defined because the characters in
between 'a' and 'z' are implementation-defined; 'a' might not
even precede 'z'. Only ranges of digits could be portable.

IIRC, a-z spans more than 26 values in EBCDIC.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long
b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return
0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case
1:putchar(a[i&15]);break;}}}

Your signature compiles with a warning:
bpsig.c:1: warning: control reaches end of non-void function

This is a corrected version, smaller of course ;-)

int putchar(int);int main(void){unsigned long b[]={0x67dffdff,0x9aa9aa6a
,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,4598},*p=b,i=24;for(;;p+=!(
*p/=4))switch(0[p]&3)case-0:{return 0;while(i-=2)case+2:{if(!++i)default
:continue;else break;case!0:putchar("\n .CJacehknorstu"[i&15]);break;}}}
 

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,997
Messages
2,570,240
Members
46,830
Latest member
HeleneMull

Latest Threads

Top