Mail Archives: djgpp/1998/07/13/17:02:01
On Sat, 11 Jul 1998 03:29:06 GMT, "David P. Hack" <hack AT sky DOT net>
wrote:
>I am a green C programmer and have a question about djgpp's handling of
>input and the scanf() function.
>
>The following program goes into a loop if a correct input is not received.
>What I expected it to do was to reprompt if a correct input is not received.
>When I compile this source and run it under Turbo C, it reprompts but under
>djgpp it loops. I assume this has something to do with djgpp's use of
>buffered input and I have read some of the bug descriptions that seem to be
>related to this but I am confused. Can anyone help me understand why this
>loops and why it runs differently from Turbo C?
>
>Thanks
>Dave Hack
>
>/* shel06.c */
>/* Validate a single character input with scanf */
>#include <stdio.h>
>#include <conio.h>
>main()
>{
> char c; /* input character */
> int intScanres; /* scanf function return value */
> clrscr();
> do
> {
> fflush(stdin);
fflush(stdin) is undefined and meaningless in Standard C and in DJGPP.
If it seems to work somehow in Borland C, this is a non-portable
compiler extension.
> printf("Please input (Y)es or (N)o: ");
> intScanres = scanf("%[YyNn]", &c);
This is _very_ unsafe. The format specifier %[ will not read
specifically _one_ character but the _longest_ sequence consisting of
any yYnY and assign it to c. If the user enters
nnnn (because his keyboard is repeating unintentionally) scanf will
assign 4 consecutive n's to the address &c and trash you memory. You
have to provide a field width 1 : %1[nNyY] for safety.
> printf("intScanres is %d\n",intScanres);
> } while(intScanres != 1);
> printf("The character entered is: %c",c);
> return 0; /* end of main() function */
>}
If you absolutely want to use scanf for character input, the sequence
should perhaps look like this:
#include <stdio.h>
int main()
{
char c;
int scanRes;
do {
puts("Enter one of [nNyY]");
scanRes=scanf(" %1[yYnN]",&c);
/* returns the first non-whitespace chararacter
and stores it to c. The blank in front of
% is _important_ */
scanf("%*[^\n]");
/* reads away every input after yYnN,
or every input if the first char
after whithespace is not in [nNyY]
_whithout_ assigning it,
leaving a pending \n which is skipped
by the leading blank in " %1[yYnY]"
*/
}
while (scanRes!=1);
/* Now the buffer will contain a pending \n.
This is normal when using scanf as all format
specifier except %c and %[ will automatically
skip leading whitespace.
A blank in a scanf format string instructs
scanf to skip every whitespace character
such as blank,tab, newline (return).
*/
return 0;
}
This sequence is quite safe for test programs - if you don't enter
Ctrl-Z or F6 which will signal an end of file.
Regards
Horst
- Raw text -