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