>On Mon, 12 Nov 2007 00:11:45 +0000, Flash Gordon
><sp**@flash-gordon.me.ukwro te:
>>1) NEVER use %s as a scanf format specifier. ...
In article <ji************ *************** *****@4ax.com>
jaysome <ja*****@hotmai l.comwrote:
>In other words, the Standard C function scanf is broken?
Essentially, yes -- but "broken" here has a number of shades of
grey:
>And if broken has no shades of gray, then scanf is as broken as
the Standard C function gets?
The scanf() function *can* be used correctly; it just takes a lot
of work. For instance:
char buf[8], stopc;
int ret;
/*
* Read up to 7 non-white-space characters and a "stop character".
*/
ret = scanf("%7s%c", buf, &stopc);
if (ret == 2) {
/*
* That worked; now inspect the "stop character" to see
* if there were characters after the 7 that would have
* been part of the "non-white-space" characters that
* %s would have scanned, to see if overlong input was
* truncated.
*/
if (isspace(stopc) )
... the non-white-space input was followed by white-space ...
else
... the non-white-space input was overlong ...
} else if (ret == 1) {
/*
* We were able to get up to 7 non-white-space characters,
* after which input must have ended due to EOF or an input
* failure, since the %c directive cannot have a matching
* failure. Decide what to do here.
*/
...
} else {
/*
* We must have ret==EOF, which means we had EOF or an
* input failure. Decide what to do here.
*/
}
In other words, it takes a big-block-o-code just to figure out what
scanf() did and recover from it in case it was not quite what you
meant for it to do. (This also still has the problem that scanf()
is quite bad for "interactiv e input", in that if the user enters
nothing but white-space -- such as a blank line -- the program may
appear to have quit running, since scanf() continues to wait for
input without printing any new prompt to the user.)
>How should a poor programmer like the OP know what is and what is not
broken in the C Standard?
Either read it very carefully, or -- much easier -- read comp.lang.c
for a long time. :-)
>And what should the poor programmer use as
alternatives in place of what is broken in the C Standard?
This depends on what one is using. For instance, as Jacob Navia
is fond of pointing out, ctime() and asctime() both behave badly
for dates in which the year needs more than four digits. To avoid
that, use strftime() instead.
>In specific, exactly what should the poor programmer use instead
of scanf?
Usually the best approach is something like fgets() (including
ggets() and similar) followed by some degree of "manual" picking
apart of the input line, using strtol(), strtod(), and/or sscanf().
The fundamental difference between using scanf() directly and using
sscanf() is that by getting an "input line" first, and only then
throwing it at the "wild and wooly" *scanf() family, you create a
buffer zone -- with a literal buffer, on which you can apply strlen()
first to verify its size -- that insulates your code from most of
the damage "plain scanf()" inflicts in practice (which is to say,
overrunning arrays; leaving behind time bombs; and/or chewing up
scads of input text that you wanted to keep, not throw away).
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it
http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.