[comp.lang.c] Curious Behaviour of "sscanf"

anderson@c10sd3.StPaul.NCR.COM (Joel Anderson) (06/17/88)

People using the C compiler on NCR Towers here in St.Paul have noted
a curious (well, at least unexpected) behaviour in the sscanf function.

On a call to sscanf as follows:
               .
               .
               .
               if (sscanf(argv[3],"X=(%d,%d)",&y,&z) == 2) 
               .
               .
               .

and an input string where argv[3] is as follows:

               "X=(1,4"

(not including the double quotes), why does sscanf in this case evaluate to
true?  Sscanf matches the number of arguments but does not continue parsing
the control string (i.e. true even though the closing paren is missing)?

Perhaps this is correct - is it?

Thanks&shalom

Joel.

scjones@sdrc.UUCP (Larry Jones) (06/20/88)

In article <236@c10sd3.StPaul.NCR.COM>, anderson@c10sd3.StPaul.NCR.COM (Joel Anderson) writes:
> On a call to sscanf as follows:
>                if (sscanf(argv[3],"X=(%d,%d)",&y,&z) == 2) 
> and an input string where argv[3] is as follows:
>                "X=(1,4"
> (not including the double quotes), why does sscanf in this case evaluate to
> true?  Sscanf matches the number of arguments but does not continue parsing
> the control string (i.e. true even though the closing paren is missing)?
> 
> Perhaps this is correct - is it?

Yep, that's the way scanf works.  The problem is not that scanf doesn't
continue parsing the control string -- it does -- the problem is that it
doesn't have any way to let you know there was a problem.  The definition
of scanf states that it returns the number of items successfully converted;
since it successfully converted 2 arguments, that's what it returned and
that's what you were expecting.

----
Larry Jones                         UUCP: ...!sdrc!scjones
SDRC                                AT&T: (513) 576-2070
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150
"When all else fails, read the directions."

jgk@speech2.cs.cmu.edu (Joe Keane) (06/20/88)

In article <236@c10sd3.StPaul.NCR.COM> anderson@c10sd3.StPaul.NCR.COM (Joel Anderson) writes:
>Sscanf matches the number of arguments but does not continue parsing
>the control string (i.e. true even though the closing paren is missing)?
>
>Perhaps this is correct - is it?

`man sscanf' (RTFM) say:

|BUGS
|     The success of literal matches and suppressed assignments is
|     not directly determinable.

So it's certainly documented.  You could argue that this isn't
`correct', but i'm not sure.  What would you have it return?

>Joel.
--Joe

jdp@adiron.UUCP (Powell) (06/21/88)

According to the "BUGS" section in scanf, the success of literal
matches and suppressed assignments is not directly determinable.

I would say the behavior indicated is correct: two (2) conversions
were successfully completed.  Perhaps but not likely, errno is set
to indicate that an inconsistency was found.


				John D. Powell
				PAR Technology

leo@philmds.UUCP (Leo de Wit) (06/27/88)

In article <307@sdrc.UUCP> scjones@sdrc.UUCP (Larry Jones) writes:
|In article <236@c10sd3.StPaul.NCR.COM>, anderson@c10sd3.StPaul.NCR.COM (Joel Anderson) writes:
|| On a call to sscanf as follows:
||                if (sscanf(argv[3],"X=(%d,%d)",&y,&z) == 2) 
|| and an input string where argv[3] is as follows:
||                "X=(1,4"
|| (not including the double quotes), why does sscanf in this case evaluate to
|| true?  Sscanf matches the number of arguments but does not continue parsing
|| the control string (i.e. true even though the closing paren is missing)?
|| 
|| Perhaps this is correct - is it?
|
|Yep, that's the way scanf works.  The problem is not that scanf doesn't
|continue parsing the control string -- it does -- the problem is that it
|doesn't have any way to let you know there was a problem.  The definition
|of scanf states that it returns the number of items successfully converted;
|since it successfully converted 2 arguments, that's what it returned and
|that's what you were expecting.

Since nobody in the scanf discussion seems to hit the real point, I will
add my share.
Larry is correct as far as the behaviour of scanf() is conceirned;
only, most people seem to think that scanf is some kind of a parser.
It is not. The best scanf can do is possibly convert its next input
characters (whether from a string, file) to the current type in the
format string. For scanf there is not such thing as a correct syntax.
It's more like a (simple) lexical analyzer. So its behaviour is what
was to be expected.
As for the example, you could modify it to

char c, s[80];

     if (sscanf(argv[3],"X=(%d,%d%c%s",&y,&z,&c,s) == 3 && c == ')') 

A bit more cumbersome, but it allows better checking (the s[] is to check
for junk after the ')').

       Leo.