scanf和scanf_s之间的差异

scanf和scanf_s之间的差异,c,visual-studio,scanf,tr24731,C,Visual Studio,Scanf,Tr24731,scanf和scanf\u之间有什么区别?在大学里,我接受过教育,我使用的是scanf,但在我的个人电脑上,visualstudio一直在发送此警告 error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. 我必须将所有scanf更改为scanf\u,否则程序将无法生成。 (我正在使用Visual Studio 2013)这是一个专门属于Microsoft编译器

scanf
scanf\u
之间有什么区别?在大学里,我接受过教育,我使用的是
scanf
,但在我的个人电脑上,visualstudio一直在发送此警告

 error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead.
我必须将所有
scanf
更改为
scanf\u
,否则程序将无法生成。
(我正在使用Visual Studio 2013)

这是一个专门属于Microsoft编译器的函数

scanf
最初只是读取您键入的任何控制台输入并将其分配给变量类型

如果您有一个名为
first\u name[5]
的数组,并且您对“Alex”使用
scanf
,则没有问题。如果您有相同的数组并分配了“Alexander”,您可以看到它超过了数组包含的5个插槽,因此C仍然会将其写入不属于该数组的内存,并且它可能会或可能不会使程序崩溃,这取决于是否有什么东西试图访问和写入不属于first_name的内存插槽。这就是
scanf_s
的用武之地


scanf_s
有一个参数,您可以在其中指定缓冲区大小并实际控制输入的限制,这样您就不会使整个建筑崩溃。

scanf_s()
不是C99标准(或以前的标准)所描述的

如果要使用针对C99(或以前版本)的编译器,请使用
scanf()

对于C11标准(以及后来的标准)
scanf_s()
scanf()
更难使用,以提高缓冲区溢出的安全性

C11
fscanf_s()

~~~~~~~~~~~~~~~~


如果您有一个C99编译器,它附带了作为扩展提供的
scanf_s()
,并且不介意失去可移植性,请查看您的编译器文档。

要避免此错误,您可以做的是在以下两者之间粘贴该内容: 去一个地方。
要到达该位置,请在解决方案资源管理器中的项目上单击鼠标右键,然后单击“属性”。然后转到配置属性,然后是c/c++,然后是预处理器。然后在预处理器定义中,在所有内容之后,添加分号并粘贴该内容。然后按apply和ok。您的问题应该得到解决。

可能的重复项与scanf相同,只是它不会导致缓冲区过载。请参阅“可以指定缓冲区大小的位置”->,这是错误的。更正:“您可以指定缓冲区大小,并且必须为类型为c、c、s、s或[]的所有输入参数指定缓冲区大小。”因此,只需向使用scanf的程序(“…%s…”,…)添加后缀“导致一个程序,该程序编译时没有警告,但不执行任何操作,因为假定缓冲区大小为0,并且不读入任何数据。实际上,在Visual Studio中,每当使用
%s
%c
时,只要没有缓冲区长度参数,
\s
函数现在是C11的一部分,并且是可移植的tions现在是C11的一部分,可移植。附录K是可选的,Microsoft实现不可移植:“Microsoft Visual Studio实现了早期版本的API。但是,该实现不完整,既不符合C11,也不符合原始TR 24731-1……由于与规范存在大量偏差,Microsoft实现不能被视为符合或可移植。“请注意,C11标准的附录K是可选的。一个实现可以声明为C11,而不提供
scanf_s()
(如果定义了(u STDC_LIB_EXT1_u)),您可以使用
。”我不会称之为“更难”这只是在扫描字符串或字符时提供缓冲区大小的问题,你应该已经在做了!