delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/07/11/18:32:05

From: "John M. Aldrich" <fighteer AT cs DOT com>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Buffered input
Date: Sat, 11 Jul 1998 18:27:38 -0400
Organization: Two pounds of chaos and a pinch of salt.
Lines: 75
Message-ID: <35A7E6DA.EA2C4522@cs.com>
References: <6_Ap1.22$s7 DOT 1149262 AT alpha DOT sky DOT net> <6o79as$913$1 AT slave1 DOT aa DOT net>
NNTP-Posting-Host: ppp104.cs.net
Mime-Version: 1.0
CC: "David P. Hack" <hack AT sky DOT net>
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Roger W. Huggins wrote:
> 
> David, you are quite right.  There is a bug in DJGPP as compared to
> Borland's scanf function.  I don't really know how to cure the problem
> except for not using scanf.  I personally do not use scanf as it is too
> limiting .  I would suggest using getch or getche depending on whether  or
> not you want the entered chartered echoed to the screen.

It's not a bug; Borland uses a highly nonstandard fflush() that somehow
manages to work on input streams.  According to the ANSI standard,
flushing an input stream is an undefined operation.  Under DJGPP, it
doesn't work; you have to clear out the input buffer yourself.

There are a couple of ways to do it:

 - char str[256];
   gets(str);
   sscanf(str, "%c", &c);

This has the advantage of simplicity, but gets() is an inherently unsafe
function as it has no way to avoid overflowing the buffer if an
extremely long line is read.

 - char str[256];
   fgets(str, 256, stdin);
   sscanf(str, "%", &c);

This works better, since if too much input is provided, fgets() stops. 
However, for maximum robustness you should detect this condition and
keep reading until the EOL shows up.

 - while ( getchar() != '\n' )
       ;
   scanf(...)

This is the simplest and easiest way to clear stdin.

Using conio functions is also possible, of course.  Just be sure not to
mix conio and stdio functions like in the code below, or at least be
very careful.  Since stdout is line-buffered by default in DJGPP, you
can get very strange results.

> Below is a modified version of your program which should work for you.
> 
> /* shel06.c */
> /* Validate a single character input with scanf */
> #include <stdio.h>
> #include <conio.h>
> main()
> {
>   char c;               /* input character */
>   int intScanres=0;       /* scanf function return value */
>   clrscr();
>   do
>   {
>     fflush(stdin);
>     printf("Please input (Y)es or (N)o:\n ");
>     c = getche();
>     if(c == 'Y' || c == 'y' || c == 'N' || c == 'n')
>       intScanres = 1;
> 
>     printf("intScanres = %d\n", intScanres);
> 
>   } while(intScanres != 1);
>   printf("The character entered is: %c",c);
>   return 0;     /* end of main() function */
> }

-- 
---------------------------------------------------------------------
|      John M. Aldrich       | "A 'critic' is a man who creates     |
|       aka Fighteer I       | nothing and thereby feels qualified  |
|   mailto:fighteer AT cs DOT com   | to judge the work of creative men."  |
| http://www.cs.com/fighteer |               - Lazarus Long         |
---------------------------------------------------------------------

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019