Substitute for gets()

Joe English jeenglis at nunki.usc.edu
Thu Feb 9 10:03:15 AEST 1989


xmjschm at hscfvax.harvard.edu (MJSchmelzer) writes:
>Given that gets() is unsafe because it doesn't check its input,
>what form of scanf() should be used?
[...]
>Another problem is if I enter, say:
>foo bar
>to this scanf-in-a-loop, it cycles through the stdin buffer twice to yield:
>foo
>bar
>I know I'm not saying this very well, sorry. But I figure this is a pretty
>basic dilemma that most folks have encountered. I mean, gets() in such a 
>loop does just fine, ie it would return "foo bar", but I have yet to
>kludge up a functionally equivalent scanf().


The truth is, scanf is pretty lousy for string
input.  It's better to use fgets(), and if that's
not quite what you want, it's a trivial job to
write your own getline() function.  Here's mine
(It doesn't do any error checking, but that's
easy to add.  I never write utility functions
with the assumption that I'm going to shoot myself
in the foot by passing a null pointer or something
like that, and I usually trust that getc() is not
going to fail):


#include <stdio.h>

/* int fgetline(FILE *fp, int size, char *buf)
   Reads characters from fp into buf, '\0'-terminates buf.
   stops when a newline is encountered or size-1
   characters have been read.  Does not store
   final newline.  size includes terminating '\0',
   so size must be at least 2.

   Returns: number of characters read (not counting \n), or -1 if
   at end of file before reading.
*/

int fgetline(FILE *fp,int size, char *buf)
{
    int n = 0,ch;

    if (feof(fp)) return -1;

    ch = getc(fp);
    while ((ch != EOF) && (ch != '\n') && (++n < size)) {
        *buf++ = (char) ch;
        ch = getc(fp);
    }

    *buf  = '\0'
    return n-1;
}
   


--Joe English

  jeenglis at nunki.usc.edu



More information about the Comp.lang.c mailing list