On Mon, 20 Feb 2012 13:25:52 +0000, Ben Bacarisse
<> wrote:
> Nick Keighley <> writes:
<snip>
> If you simply must get your gets-containing code to run today, you can use:
>
> #define gets(s) (scanf("%[^\n]%*c", (s)) == 1 ? (s) : NULL)
>
> but you should fix it tomorrow! (Not you personally, of course, but
> "one" is sometimes too formal for Usenet).
Not quite. That gets 'stuck' on an empty line (newline only).
You need to split the call like
( scanf ("%[^\n]", (s)) == 1 ? scanf ("%*c"), (s)
: (scanf ("%*c"), NULL ) )
or you can substitute getchar (or getc(stdin) etc)
( scanf ("%[^\n", (s)) == 1 ? getchar(), (s) : ( getchar(), NULL ) )
And of course it usually evaluates s twice and thus is wrong for an
argument that is not idempotent (often inexactly stated as having side
effects). One could argue that using gets() that way is a bad idea --
but then using gets() at all is a bad idea!
By this point it isn't really fun anymore. If it was necessary (which
as Keith says it's not) I'd just write something straightforward like
char * gets (char * s){
size_t i = 0; int c;
while ( (c = getchar()) != EOF && c != '\n' ) s[i++] = c;
if (c == EOF && i == 0) return NULL;
s[i] = 0; return s;
}
or the obvious pointer equivalent.
Or to be (extra) cautious about the external name, I might write it as
another name like mygets and #define gets to that.
|