Most of the answers so far seem to focus on the string buffer overflow issue. In reality, the format specifiers that can be used with scanf
functions support explicit field width setting, which limit the maximum size of the input and prevent buffer overflow. This renders the popular accusations of string-buffer overflow dangers present in scanf
virtually baseless. Claiming that scanf
is somehow analogous to gets
in the respect is completely incorrect. There's a major qualitative difference between scanf
and gets
: scanf
does provide the user with string-buffer-overflow-preventing features, while gets
doesn't.
One can argue that these scanf
features are difficult to use, since the field width has to be embedded into format string (there's no way to pass it through a variadic argument, as it can be done in printf
). That is actually true. scanf
is indeed rather poorly designed in that regard. But nevertheless any claims that scanf
is somehow hopelessly broken with regard to string-buffer-overflow safety are completely bogus and usually made by lazy programmers.
The real problem with scanf
has a completely different nature, even though it is also about overflow. When scanf
function is used for converting decimal representations of numbers into values of arithmetic types, it provides no protection from arithmetic overflow. If overflow happens, scanf
produces undefined behavior. For this reason, the only proper way to perform the conversion in C standard library is functions from strto...
family.
So, to summarize the above, the problem with scanf
is that it is difficult (albeit possible) to use properly and safely with string buffers. And it is impossible to use safely for arithmetic input. The latter is the real problem. The former is just an inconvenience.
P.S. The above in intended to be about the entire family of scanf
functions (including also fscanf
and sscanf
). With scanf
specifically, the obvious issue is that the very idea of using a strictly-formatted function for reading potentially interactive input is rather questionable.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…