What's the difference between gets and scanf?
The basic difference [in reference to your particular scenario],
scanf()
ends taking input upon encountering awhitespace
,newline
orEOF
gets()
considers a whitespace as a part of the input string and ends the input upon encounteringnewline
orEOF
.
However, to avoid buffer overflow errors and to avoid security risks, its safer to use fgets()
.
Disambiguation: In the following context I'd consider "safe" if not leading to trouble when correctly used. And "unsafe" if the "unsafetyness" cannot be maneuvered around.
scanf("%s\n",message)
vs
gets(message)
What's the difference?
In terms of safety there is no difference, both read in from Standard Input
and might very well overflow message
, if the user enters more data then message
provides memory for.
Whereas scanf()
allows you to be used safely by specifying the maximum amount of data to be scanned in:
char message[42];
...
scanf("%41s", message); /* Only read in one few then the buffer (messega here)
provides as one byte is necessary to store the
C-"string"'s 0-terminator. */
With gets()
it is not possible to specify the maximum number of characters be read in, that's why the latter shall not be used!
The main difference is that gets
reads until EOF or \n
, while scanf("%s")
reads until any whitespace has been encountered. scanf
also provides more formatting options, but at the same time it has worse type safety than gets
.
Another big difference is that scanf
is a standard C function, while gets
has been removed from the language, since it was both superfluous and dangerous: there was no protection against buffer overruns. The very same security flaw exists with scanf however, so neither of those two functions should be used in production code.
You should always use fgets
, the C standard itself even recommends this, see C11 K.3.5.4.1
Recommended practice
6 The fgets function allows properly-written programs to safely process input lines too long to store in the result array. In general this requires that callers of fgets pay attention to the presence or absence of a new-line character in the result array. Consider using fgets (along with any needed processing based on new-line characters) instead of gets_s.
(emphasis mine)