Ignore return value of a gobble-only scanf (gcc)

2019-09-11 05:52发布

问题:

So I've read this question and other related questions, and I know that it's a good idea to check the return value of scanf to avoid surprises. But I have the following scanf in my code:

/*
 * If we don't gobble newlines,
 * then they'll be interpreted as commands.
 * Gobble both \n and \r (because the input files use 0x0D).
 */
(void) scanf("%*[\n\r]");

As you can see, I'm casting the result of scanf to void, but GCC still warns under -ansi -pedantic -Wall -O3, as noted here.

Is there anything clean I can do to suppress this warning without compiler-specific directives—that is, in pure ANSI C90? (By clean I mean no if (scanf(...)); or similar.)

回答1:

GCC 4.4 does warn in this case, but 4.7 and 4.9 do not. This lines up with the claim in that GCC bug you linked that it was fixed in 4.5. So one option is to use a version of the compiler less than five years old.

If you're stuck with GCC 4.4 or older, you can do this:

int dummy = scanf("%*[\n\r]");
(void)dummy;

This should be a familiar pattern to many C or C++ programmers.

If for some reason you object to using two statements and don't want to create an ignore() function as suggested by @pm100, you could also do this:

abs(scanf("%*[\n\r]"));

I would much prefer the (void)dummy solution though.

Finally, you could avoid scanf() altogether and do something like this (untested, not 100% sure it does what you need):

int ch;
do {
  ch = getchar();
} while (ch == '\r' || ch == '\n');
ch = ungetc(ch, stdin);
assert(ch != EOF);

Obviously you'd put that all in a nice little function with a descriptive name, which is probably a good idea with the scanf() solutions too.