[comp.lang.c] Number of characters buffered by stdio detection.

diomidis@ecrcvax.UUCP (Diomidis Spinellis) (04/26/89)

I want to use select(2) on an stdio buffered stream.  The problem
is that before calling select I need to check if there are any
characters in the buffer.  I have not found any function that
returns such a value, so I use _iob(x)->_cnt.  This is not part
of the documented stdio interfaces and thus non-portable.  Is there
a better way to do this?

--
Diomidis Spinellis
European Computer Industry Research Centre

ka@june.cs.washington.edu (Kenneth Almquist) (05/04/89)

> I want to use select(2) on an stdio buffered stream.  The problem
> is that before calling select I need to check if there are any
> characters in the buffer.  I have not found any function that
> returns such a value, so I use _iob(x)->_cnt.  This is not part
> of the documented stdio interfaces and thus non-portable.  Is there
> a better way to do this?

I would bypass stdio entirely, and just use "read".  If you need to
get characters one at a time, writing your own version of getc is
straightforward (see below).  Relying on the internals of stdio is
a bad idea, because they are not documented, and can change over
time.  Using "read" directly may make your code a little bigger, but
it will make it more readable, more maintainable, and more portable.
				Kenneth Almquist



/*
 * Example illustrating how to write your own getc.  The variables
 * should be put into a structure if you need to read more than one
 * file at once.
 */

#define mygetc()	(--nleft >= 0? *nextc++ : readbuffer())

char inbuf[BUFSIZ];	/* input buffer */
int nleft;		/* characters in input buffer */
char *next;		/* next unread character in input buffer */
int infd;		/* input file descriptor */

int
readbuffer() {
      register int i;

      nextc = inbuf;
      i = read(infd, inbuf, BUFSIZ);
      if (i <= 0)
	    return EOF;
      nleft = i - 1;
      return *nextc++;
}