From: horst DOT kraemer AT snafu DOT de (Horst Kraemer) Newsgroups: comp.os.msdos.djgpp Subject: Re: Buffered input Date: Mon, 13 Jul 1998 20:57:36 GMT Organization: Unlimited Surprise Systems, Berlin Lines: 96 Message-ID: <35aa57ab.28188165@news.snafu.de> References: <6_Ap1.22$s7 DOT 1149262 AT alpha DOT sky DOT net> NNTP-Posting-Host: n33-177.berlin.snafu.de To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk On Sat, 11 Jul 1998 03:29:06 GMT, "David P. Hack" 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 >#include >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 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