scanf
和scanf_s
有什么区别?在大学里我学的是并一直使用的是scanf
,但在我的个人电脑上,Visual Studio一直发出这个警告。
error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead.
我必须将所有的scanf
更改为scanf_s
,否则程序无法构建。
(我正在使用Visual Studio 2013)
scanf
和scanf_s
有什么区别?在大学里我学的是并一直使用的是scanf
,但在我的个人电脑上,Visual Studio一直发出这个警告。
error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead.
我必须将所有的scanf
更改为scanf_s
,否则程序无法构建。
(我正在使用Visual Studio 2013)
这是一个专属于Microsoft编译器的函数。
scanf
最初只是读取你键入的控制台输入并将其分配给变量类型。
如果你有一个名为first_name [5]
的数组,并使用scanf
输入"Alex",那没有问题。但如果你使用相同的数组并输入"Alexander",你会发现它超出了数组包含的5个插槽,所以C仍然会将其写入不属于该数组的内存中,这可能导致程序崩溃,具体取决于是否有东西尝试访问并写入不属于first_name的内存槽。这就是scanf_s
发挥作用的地方。
scanf_s
有一个参数(参数),您可以在其中指定缓冲区大小并实际控制输入限制,以避免使整个程序崩溃。
%s
或%c
时发出警告。 - Anders Marzi Tornblad_s
函数现在已成为 C11 的一部分并且可移植。Annex K 是可选的,而 Microsoft 实现则不可移植。根据《Annex K 与界限检查接口的实战经验》(Field Experience With Annex K — Bounds Checking Interfaces): “Microsoft Visual Studio 实现了较早版本的 API,但该实现是不完整的,既不符合 C11 标准也不符合原始的 TR 24731-1 标准...由于许多偏离规范的地方,Microsoft 实现不能被认为是符合标准或者可移植的。” - Andrew Henlescanf_s()
在C99标准(以及之前的标准)中没有被描述。
如果您想使用面向C99(或之前版本)的编译器,请使用scanf()
。
对于C11标准(以及以后的标准),scanf_s()
比scanf()
更难使用,但可以提供更好的安全性以防止缓冲区溢出问题。
C11 fscanf_s()
: http://port70.net/~nsz/c/c11/n1570.html#K.3.5.3.2
~~~~~~~~~~~~~~~~
如果您有一个提供scanf_s()
作为扩展功能的C99编译器,并且不介意失去可移植性,请检查您的编译器文档。
scanf_s()
函数(您可以使用#if defined(__STDC_LIB_EXT1__)
来检查)。 - pmg
scanf
相同,只是不会导致缓冲区溢出。 - David Ranieri