Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!bbn!oberon!nunki.usc.edu!jeenglis From: jeenglis@nunki.usc.edu (Joe English) Newsgroups: comp.lang.c Subject: Re: Substitute for gets() Message-ID: <2633@nunki.usc.edu> Date: 9 Feb 89 00:03:15 GMT References: <721@hscfvax.harvard.edu> Reply-To: jeenglis@nunki.usc.edu (Joe English) Distribution: na Organization: University of Southern California, Los Angeles, CA Lines: 62 xmjschm@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 /* 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@nunki.usc.edu