[comp.lang.c] fscanf

vaes@cs.ruu.nl (Illya Vaes) (04/23/91)

In <1991Apr23.075320.9473@en.ecn.purdue.edu> tenka@en.ecn.purdue.edu (Andy Tenka) writes:

>I am writing a program which will take its input from
>both stdin (redirected from a file) and the keyboard.
>In desperation to get the input from keyboard, I used:
>
>	fscanf(stderr,"%d",&i);
>
>However, the fscanf does not wait for input from keyboard.
>It just reads 0 from stderr before I even type anything.
>I know I did something wrong here.  Could any of you gurus
>point out my mistakes and also, could you show me a way to
>write a program that takes input from both redirected stdin
>and keyboard?  Many thanks in advance.
>
>Andy

As far as I know, stderr is only for output, so you cannot read
from it. Yo probably best look on your terminal as two seperate
devices: one for giving input to the system and one for showing
output of the system to the user. Stderr uses the last one.
If you want to read from the keyboard as well as from a file, 
the most obvious thing to do is leaving the standard input intact
and opening the file to read from (with open(2)), using its file
descriptor in fscanf:
	 
	/* watch the #includes */

	FILE *file;

	file= fopen ("myfile", "r");	/* open "myfile" for reading */

	read_chars= fscanf (file, "%d", &i);
	if (read_chars ...) {
	}
	else {
	}

	... = fscanf (stdin, "...", ...);
	... = scanf ("...", ...);	/* equivalent to fscanf(stdin...) */

Hope to have helped,

Illya.

-- 
+---------------------------------------------------------------------+
|  vaes@cs.ruu.nl  UNTIL 31 May 1991.				      |
|  								      |
|  "I think, therefore I am not what I think I am" (Me, Myself and I) |

heinhuis@dri.nl (Gustaaf-Jan Heinhuis) (04/23/91)

In article <1991Apr23.075320.9473@en.ecn.purdue.edu> 
tenka@en.ecn.purdue.edu (Andy Tenka) writes:

>In desperation to get the input from keyboard, I used:
>
>	fscanf(stderr,"%d",&i);
>
>However, the fscanf does not wait for input from keyboard.
>It just reads 0 from stderr before I even type anything.
>I know I did something wrong here.  Could any of you gurus
>point out my mistakes

Ever tried to read from screen??????? 
Since when is stderr linked to a keyboard?????!!!!!!!!

The kernel links stdin to the keyboard (_iob[0]), stdout an stderr to the
screen (_iob[1] and _iob[2] resp.) *****before***** the program starts.
Redirecting results in the kernel linking stdin to the file instead of to
the keyboard.

>and also, could you show me a way to
>write a program that takes input from both redirected stdin
>and keyboard?  Many thanks in advance.

This is elementary (do hope I will not regret this remark, no flames)

You simply open a file for reading ( fopen(filename, "w") ). You have 
three options:
      1): supply filename as an argument to your program.
      2): let the user supply the filename ( scanf("%s", &name) )
      3): you always read from the same file, i.e. filename is a string
	  constant.

Hope this helps, Gustaaf-Jan.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++---===To all virgins, thanks for nothing.===---++++++++++++++
          
   ___              GJ Heinhuis student comp. sc. HIO Enschede (Holland)
  /  _)             Final Project at: DataCount, Wierden, Holland
 |  ____ ___        Mail: heinhuis@dri.nl
  \__/|   |         
      |___|         Everybody is entitled to his own	
  |   |   |         opinion, as long as it's mine!
   \_/    |         Not necessarely DataCount's opinion!!

tom@itc.univie.ac.at (Tom Kovar) (04/24/91)

In article <1991Apr23.075320.9473@en.ecn.purdue.edu> tenka@en.ecn.purdue.edu (Andy Tenka) writes:
>I know I did something wrong here.  Could any of you gurus
>point out my mistakes and also, could you show me a way to
>write a program that takes input from both redirected stdin
>and keyboard?  Many thanks in advance.
>

 ... I would suppose the simplest way how to read parallely from stdin an from
the keoboard would be to open /dev/tty for the keyboard input...
									Tom

rjohnson@shell.com (Roy Johnson) (04/24/91)

In article <1010@dri500.dri.nl> heinhuis@dri.nl (Gustaaf-Jan Heinhuis) writes:
>In article <1991Apr23.075320.9473@en.ecn.purdue.edu> 
>tenka@en.ecn.purdue.edu (Andy Tenka) writes:

>>and also, could you show me a way to
>>write a program that takes input from both redirected stdin
>>and keyboard?  Many thanks in advance.

>This is elementary (do hope I will not regret this remark, no flames)

>You simply open a file for reading ( fopen(filename, "w") ). You have 
>three options:
>	 1): supply filename as an argument to your program.
>	 2): let the user supply the filename ( scanf("%s", &name) )
>	 3): you always read from the same file, i.e. filename is a string
>	     constant.
Fine, unless you want to use it as a pipe and still get input from
the user.

On a UNIX system, you can use the (redirected) stdin as it is, and
read from keyboard input using

FILE *keyboard;

keyboard = fopen("/dev/tty", "r");
--
=============== !You!can't!get!here!from!there!rjohnson ===============
Feel free to correct me, but don't preface your correction with "BZZT!"
Roy Johnson, Shell Development Company

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (04/26/91)

In article <1010@dri500.dri.nl>, heinhuis@dri.nl (Gustaaf-Jan Heinhuis) writes:
> Ever tried to read from screen??????? 
> Since when is stderr linked to a keyboard?????!!!!!!!!

In UNIX, stderr is typically what you'd get from
	stderr = fdopen(2, "w");
It doesn't make sense to read from stderr, because it's set up as an
output file.  But the standard error descriptor, if it is connected to
a terminal (which it need not be) is bidirectional, and it does make
sense to read from it.  So
	FILE *ttyin = fdopen(2, "r");
might well work.

> >and also, could you show me a way to
> >write a program that takes input from both redirected stdin
> >and keyboard?  Many thanks in advance.

The best answer that I know of is to open a new stream to the terminal.
Leave stdin connected to whatever it is connected to by the caller, then
in UNIX, just do
	FILE *ttyin = fopen("/dev/tty", "r");
In MS-DOS, I guess
	FILE *ttyin = fopen("con", "r");
might work.

<-- 
Bad things happen periodically, and they're going to happen to somebody.
Why not you?					-- John Allen Paulos.

bush@iccgcc.decnet.ab.com (06/25/91)

Date: 24 Jun 91 12:44:00 EDT
From: " 24960,  BUSH,STEVEN" <bush@iccgcc.decnet.ab.com>
Subject: fflush()? fscanf() fgets() problem.
To: "whitbeck" <whitbeck%sanjuan.uucp@abvax.icd.ab.com>

X-News: iccgcc comp.lang.c:10700

>From: whitbeck@sanjuan.wrcr.unr.edu (Mike Whitbeck)
>Subject:fflush()? fscanf() fgets() problem.
>Date: 31 May 91 06:44:57 GMT
>Message-ID:<456@equinox.unr.edu>

>I have a problem using fscanf() and fgets() and was wondering
>if it had something to do with fflush() {I guess I just don't
>know what fflush() is for!}
>
>I open a file
>	fp = fopen("file","r");
>
>and then I read some stuff
>	fscanf(fp,"%f\n",&fv);
>then later I try to suck in a line as a text string
>	fgets(str,n,fp);
>Elsewhere I have used fgets() to read in a line
>but here it fails! (gets only the first 'word' (whitespace
>delimited) from the line.
>As a workaround I use a loop
>	for (...) {
>		fscanf(fp,"%s",dummy);
>		strcat(line," "); 
>		strcat(line,dummy);
>		}
>ICK!
>
>What's going on here? Is fscanf() known to mess up fgets()? or
>is this unique to me? [I am using a SUN 3/80].
>
>HELP!

The problem that you speak of is a common pitfall that most C programmers 
experience at some point in time.  The problem is not really a problem.
The function fscanf() is much like the function scanf().  fscanf() like
scanf() stops reading input at the newline character.  At that point in time,
the newline character is still in the input buffer, and is NOT read.  fgets()
on the other hand reads everything including the newline character.  If you
follow a call to fscanf() by a call to fgets(),  all fgets() will read is the
newline character that fscanf() doesn't scan.  The result looks as if fgets()
fails when all it read was a newline.  One way around this side effect is to
always follow scanf() or fscanf() by getc() or fgetc() like the following:

	fscanf("%f",&float_value);  /* read a floating point value */
	fgetc(stdin);               /* read the newline character  */
	fgets(string_array);        /* read a string               */

The fflush() function is used only to flush output buffers to disk.  When 
working with files, output information goes into a disk buffer, which when
full, is flushed to disk by the operating system.  All that fflush() does
is to allow you to force the operating system to write a disk buffer to
disk when it is not completely full.

chupchup@piggy.ucsb.edu (Robert Earl) (06/25/91)

In article <1991Jun24.132920.4956@iccgcc.decnet.ab.com> bush@iccgcc.decnet.ab.com writes:

|   The fflush() function is used only to flush output buffers to disk.  When 
|   working with files, output information goes into a disk buffer, which when
|   full, is flushed to disk by the operating system.  All that fflush() does
|   is to allow you to force the operating system to write a disk buffer to
|   disk when it is not completely full.

Wrong: fflush() forces the stdio implementation to flush its internal buffer,
whether it be block-buffered, line-by-line, or none, by doing (for example) a
write() system call.  After that, the operating system can do what it likes in
buffering data to be written to a terminal, file, pipe, or whatever.


An alternative to using scanf() and fscanf() on interactive input is to use
fgets(), and then sscanf() the resulting string.  I think this is an FAQ.

--
______________________________________________________________________
			\
 robert earl		/	"Love is a many splintered thing"
 rearl@piggy.ucsb.edu	\		--Sisters of Mercy