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
.