how gets() work after scanf?
This question already has an answer here:
scanf("%d", &num);
without a space after the "%d"
, stops scanning after reading a number. So with input 123Enter, the 'n'
remains in stdin
for the next input function like the now non-standard gets()
. gets()
reads that single 'n'
and returns. By adding a space, scanf("%d ", &num);
consumes the white-space after the number and does not return until non-white-scape is entered after the number.
By adding a space, scanf("%d ", &num);
does not return until non-white-space is entered after the number (as in 'a'
in the following). Since stdin
is usually line buffered, this means input of 2 lines needs to first occur. 123Enter abcEnter.
Recommend to instead use fgets()
to read a line of user input.
char str[10*2]; // no need for such a small buffer
int num;
printf("Enter your number : ");
fflush(stdout);
fgets(str, sizeof str, stdin);
sscanf(str, "%d", &num);
printf("%dn",num);
printf("Enter data : ");
fflush(stdout);
fgets(str, sizeof str, stdin);
fputs(str, stdout);
More robust code would check the results of fgets(), sscanf()
and use strtol()
rather than sscanf()
.
The C FAQ covers all these problems with scanf
. See Why does everyone say not to use scanf? What should I use instead? and associated entries. Generally you'll use fgets
followed by processing the resulting line such as with sscanf
and checking that sscanf
succeeded. This avoids leaving unparsed input and risking an infinite loop.
int number;
char line[255];
fgets( line, sizeof(line), stdin );
if( sscanf( line, "%d", &number ) != 1 ) {
fputs("That doesn't look like a number.n", stdin);
}
Note that fgets
will read to a newline or as much as your buffer can hold. If the line is larger than your buffer, it might only read part of the line. Next read from input will get the rest of the line. There's ways to avoid this, such as the POSIX getline function, but at least you don't wind up in an infinite loop.
Let's decipher some comments.
Do not ever use gets
. Use fgets
.
The reason you don't use gets
is because there's no way to limit how much is read from stdin
. This means the user can overflow the buffer causing havoc.
char buffer[32];
// What the line is more than 31 characters?
gets(buffer);
fgets()
takes the size of the buffer and will read that many characters at most. This prevents a buffer overflow.
char buffer[32];
// If there's more than 31 characters it will stop reading.
// The next read of stdin will get the rest of the line.
fgets( buffer, sizeof(buffer), stdin );
"There's no gets()
function in C."
Yes, there is a gets()
function in C.
Yes, there isn't a gets()
function in C.
It depends on which C you're talking about.
Some people when they say "C" mean C11, the current standard. Others when they say "C" mean C99 the previous standard. Some still adhere to C90, the original standard. There is a gets()
function in C90. It was deprecated in C99. It was removed from the language in C11.
C compilers and documentation lag very, very, very far behind the standard. Many are still working on full support of C99. If you work to C11 you're going to be very surprised by the lack of support. If you want your code to work on most any compiler, write to C99.
Anyway, don't use gets
.
上一篇: “x = x ++”后的x是什么?
下一篇: get()如何在scanf之后工作?