[comp.lang.c] field width in scanf for reals

engber@shorty.CS.WISC.EDU (Mike Engber) (05/24/89)

I've found that when reading reals in exponential format using scanf
with a field width specifier that the e for the exponent doesn't seem
to count as part of the field width. To read 1.2e3 you need to use
"%4f". I've tried this out on several UNIX machines and they all seem
to have the same bug/feature. The SUN compiler, however, worked as
you'd expect.  It needed a field width of 5.

Does anyone have an explanation of all this. I assume it's compiler bugs.

please respond via email

-ME

scs@adam.pika.mit.edu (Steve Summit) (05/28/89)

In article <7562@spool.cs.wisc.edu> engber@shorty.cs.wisc.edu (Mike Engber) writes:
>I've found that when reading reals in exponential format using scanf
>with a field width specifier that the e for the exponent doesn't seem
>to count as part of the field width. To read 1.2e3 you need to use
>"%4f".

Mike is correct; many versions of *scanf are buggy in this
regard.  (The fault lies in the C library implementation, not the
compiler.)  More precisely, scanning a string like "1.2e12" with
format %5f yields 1.2e12, not 1.2e1, because the count of
characters consumed is not decremented when the 'e' is scanned.

I discovered this problem when writing my own version of scanf.
Not having used scanf much, I hadn't thought about its field
width specification convention or its implementation implications;
I was rather appalled to discover what a royal pain correct
implementation turned out to be.  There are six or seven loops
within which characters are consumed; a straightforward
implementation requires that each of these loops decrement the
running field width (if present) and terminate prematurely if it
reaches 0, at the cost either of a subroutine call per character
or a lot of duplicated code.  (There may well be a more clever
implementation which could handle field width more transparently
or automatically.  Since I neither use scanf much nor encourage
its use, I didn't work too hard polishing my implementation.)
I was pleased to discover that the implementor of the "standard"
version evidently found the issue as troublesome as I did.

Are you sure you need to be using scanf field widths in the first
place?  Most of the time, the appropriate format for reading
1.2e3 is neither %4f nor %5f but simply %f, which will of course
work correctly regardless of field width bugs.

Scanf field widths strike me as being a rather esoteric feature
whose use shouldn't often be required.  (Perhaps that's why bugs
persist.)  You'd only need field widths when dealing with rigid
columnar input formats a la Fortran; most of the time you're much
better off using whitespace or other syntactic field separators,
in which case widthless scanf formats work fine (if you must use
scanf at all).

                                            Steve Summit
                                            scs@adam.pika.mit.edu