This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: scanf conflict with ANSI/ISO C99 fscanf Example 3 -- glibc scanf accepting invalid integer and floating point strings


Hello,

On Sat, Sep 13, 2003 at 03:04:20PM +0200, Andreas Jaeger wrote:
> mjn3@codepoet.org (Manuel Novoa III) writes:
> >
> > #include <stdio.h>
> > #include <stdlib.h>
> >
> > int main(void)
> > {
> >     int count;
> >     float quant;
> >     char units[21], item[21];
> >
> >     count = sscanf("100ergs of energy", "%f%20s of %20s", &quant, units, item);
> 
> 100 ergs of energy...
> 
> 100e is the initial suffix for a floating point number which cannot be
> parsed correctly, so your input is wrong,

Sigh... I know that "100e" the initial prefix for a floating point
number which can't be parsed correctly by scanf.  That's the point.
I suppose I assumed incorrectly that people would have a copy of
the ANSI/ISO C99 standard on hand.  So, here's the original
example copied from the standard.

************************************************************************

19) EXAMPLE 3 To accept repeatedly from stdin a quantity, a unit of
measure, and an item name:

#include <stdio.h>
/* ... */
int count; float quant; char units[21], item[21];
do {
    count = fscanf(stdin, "%f%20s of %20s", &quant, units, item);
    fscanf(stdin,"%*[^\n]");
} while (!feof(stdin) && !ferror(stdin));

20) If the stdin stream contains the following lines:

2 quarts of oil
­12.8degrees Celsius
lots of luck
10.0LBS of dirt
100ergs of energy

the execution of the above example will be analogous to the following
assignments:

quant = 2; strcpy(units, "quarts"); strcpy(item, "oil");
count = 3;
quant = ­12.8; strcpy(units, "degrees");
count = 2; // "C" fails to match "o"
count = 0; // "l" fails to match "%f"
quant = 10.0; strcpy(units, "LBS"); strcpy(item, "dirt");
count = 3;
count = 0; // "100e" fails to match "%f"
count = EOF;

************************************************************************

I simply isolated the "100ergs of energy" test string in my posted
test.  Here's the output illustrating how glibc handled this case.

> > count = 3
> > Error! count should be 0, as per Example 3 for fscanf in the ANSI/ISO C99 spec.
> > quant = 100.000000
> > units = "rgs"
> > item = "energy"

So, instead of glibc's scanf failing with a matching failure for "%f" as
it should have, it accepted "100E" as a valid floating point string,
assigned 100 to quant, and then continued processing.  It went on to
set units to "rgs" (notice the missing 'e') and items to "energy".

The remaining tests illustrated the fact that glibc's scanf is
accepting floating point and integer strings as valid when they
are missing digits in required places.

Is that clearer?

Manuel


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]