🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c
Article #3683

Re: gets() and getchar

#3683
From: Richard A. O'Keefe
Date: Wed, 09 Aug 1995 05:34
106 lines
4454 bytes
Jens Andreasen <jens-and@dsv.su.se> writes:
>Well, getchar() seems to be a bit on the implementation defined side and
>gets() can be considered playing russian roulette :-|

Which is why my shell script for compiling C has
	-Dgets=DONT_USE_GETS
in it, amongst other things.  Forget who suggested that on the net, but it
was a good idea.

However, getchar() is the same as getc(stdin), and getc() is the fundamental
way of reading from a stream in C.  gets(), fgets(), fread(), and so on all
act _is if_ they worked by calling getc().

>And having to use implementation defined substitutes is like throwing
>std.c out the window.

>Is there any convention for how many chars gets will actually read,

Yes of course.  The standard is crystal clear:
	The gets function reads characters from the input stream
	pointed to by stdin, into the array pointed to by s,
    -->	until end-of-file is encountered or a new-line character is read.
	Any new-line character is discarded, and a null character is
	written immediately after the last character read into the array.

>Seriously, why not make such a convention or standard?

Because there _is_ a standard which already says what gets() does,
and people are allowed to rely on it.

>I'd suggest 256 chars to be sufficient for my needs,
>others may prefer 1k or maybe 16k...

Myself, I don't see any particular magic in 256.
>So IMHO a solution could be to introduce a systemvariable: MAX_GETS


No, the solution is for you to write your OWN function.

Here's the existing gets():

	char *gets(char *buffer) {
	    char *p = buffer;
	    int c;

	    while ((c = getchar()) != EOF && c != '\n')
		*p++ = c;
	    *p = '\0';
	    return c == '\n' || p != buffer ? buffer : (char *)0;
	}

That's it.  Honestly.  It doesn't do anything you can't do.
(It may do it more efficiently, but if you're reading from a keyboard
that's the least of your worries.)

If you want a bounded gets, do it like so:

	size_t my_gets_limit = 256;

	char *my_gets(char *buffer) {
	    char *p, *e;
	    int c;

	    for (e = (p = buffer) + my_gets_limit; p != e; *p++ = c)
		if ((c = getchar()) == EOF || c == '\n') {
		    *p = '\0';
		    return c == '\n' || p != buffer ? buffer : (char*)0;
		}
	    *p = '\0';
	    return p != buffer ? buffer : (char *)0;
	}

If my_gets_limit == 0, I am counting the resulting read as unsuccessful
so that you won't go into an infinite loop reading empty strings.  This
is debatable; maybe it should count as a successful read of 0 bytes.

Better yet, you could learn about fgets().

>Or do anybody know of a workaround using getchar that won't hang this or
>that odd system because of chars left in the buffer? (Remember, the cat 
>*could* be part of the system). 

What do you mean "hang"?  Come to that, just _which_ buffer do you mean?

>And while I'm at it, how about a useful thing like user_pressed_a_key()
>or chars_left_in_buffer()?

The answers-to-frequently-asked questions (FAQ) of comp.lang.c answer
this and many other questions.  To start with,
	- what's a user?  C is used on systems that _have_ no user.
	- what makes you think the computer can _tell_ if the user
	  (assuming one to exist) pressed a key?  If you are using
	  a remote connection with local line editor, it _can't_.
	  (Or for that matter if you are running a program under
	  Jove, or Emacs, or ILE, or ...)
	- which buffer?  If you are worried about stdio buffers, you
	  can make sure there _isn't_ one by calling setbuf(stdin, NULL);
	  If you are worried about operating system buffers, the question
	  is a bit tricky.  Just because I flushed my Event Queue one
	  nanosecond ago is no guaranteed there isn't a keypress event
	  in it _now_... 

-- 
"conventional orthography is ... a near optimal system for the
 lexical representation of English words." Chomsky & Halle, S.P.E.
Richard A. O'Keefe; http://www.cs.rmit.edu.au/~ok; RMIT Comp.Sci.
Technical Details
Message-ID: <409hdq$ib2@goanna.cs.rmit.edu.au>
Path: arc1-ca.pugleaf.net!goanna.cs.rmit.edu.au!not-for-mail
References: <Pine.ULT.3.91.950807194041.19202A-100000@mars>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!goanna.cs.rmit.edu.au!not-for-mail
From: ok@goanna.cs.rmit.edu.au (Richard A. O'Keefe)
Newsgroups: comp.std.c
Subject: Re: gets() and getchar
Date: 9 Aug 1995 15:34:50 +1000
Organization: Comp Sci, RMIT, Melbourne, Australia
Message-ID: <409hdq$ib2@goanna.cs.rmit.edu.au>
References: <Pine.ULT.3.91.950807194041.19202A-100000@mars>
NNTP-Posting-Host: goanna.cs.rmit.edu.au
NNTP-Posting-User: ok
X-Newsreader: NN version 6.5.0 #0 (NOV)