Article View: comp.std.c
Article #3683Re: gets() and getchar
From: Richard A. O'Keefe
Date: Wed, 09 Aug 1995 05:34
Date: Wed, 09 Aug 1995 05:34
106 lines
4454 bytes
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-mailReferences:
<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)