VS中C语言安全函数怎么回事?如何解决?
作者丨李肖遥
ID丨技术让梦想更伟大
在 VS(Visual Studio)下编译C语言程序,如果使用了 scanf()、gets()、strcpy()、strcat() 等与字符串读取或操作有关的函数,有时候VS会报错.
举例子代码如下:
//#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int a;
scanf("please enter a num:%d", &a);
printf("the data is %d",a);
system("pause");
return 0;
}
编译结果如下图所示:
C4996 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
意思是此函数或变量可能不安全,考虑使用 scanf_s 代替,要禁用弃用,请使用 _CRT_SECURE_NO_WARNINGS
,这个我们稍后讲到。
什么是安全函数(safe function)?
上述与字符串读取或操作有关的函数都是C语言标准函数,可能会导致数组溢出或者缓冲区溢出,存在安全问题,就是怕引起缓冲区溢出
攻击,这个具体的咱不讲。
先说明,Visual Studio
指Microsoft Visual Studio
,是美国微软公司的开发工具包系列产品,而从上面的编译结果可以看到,scanf()
提示要编成scanf_s()
,这些后缀是_s
的函数是微软自己发明的安全函数且仅适用于 VS。
这些安全函数在读取或操作字符串时要求指明长度,这样一来,过多的字符就会被过滤掉,避免了数组或者缓冲区溢出。
以 scanf_s() 为例来讲解。
C 库函数原型int scanf(const char *format, ...)
从标准输入 stdin 读取格式化输入。
format 说明符形式为:
[=%[*][width][modifiers]type=]
其中width指定了在当前读取操作中读取的最大字符数,但scanf() 在读取字符串时不会检查字符个数,例如:
char buffer[5]={0};
scanf(“%s”, buffer);
当用户输入lixiaoyao
这些字符时,scanf() 会全部读取并放入 buffer 中,但是 buffer 最多只能存储 5 个字符,而多出来的就会存在后面。
但是buffer 后面的内存不一定有使用权限,这样会导致程序在运行时可能会出现不可预知的错误。由于C语言的特性,这种代码在编译期间无法检测,就会导致程序崩溃死掉。
scanf_s()传入一个和参数有关的大小值,使用 scanf_s() 代替 scanf(),这样就可以控制数组或者缓冲区输入的大小了,代码如下:
char buffer[5] = {0};
scanf_s(“%s”, buffer, 5);
注意:安全函数是微软自己发明的,只适用于 VS 编译器,在其他编译器下无效。
如何取消安全函数的限制
对 VS 做适当的设置
VS 之所以会提示使用安全函数,是因为它进行了SDL检查即安全性开发生命周期检查,我们而已手动取消。
菜单栏中选择设置如下图所示:
弹出一个对话框,选择“C/C++ --> SDL检查”,如下设置如下图所示:
_CRT_SECURE_NO_WARNINGS
开头的代码编译结果说到,请使用 _CRT_SECURE_NO_WARNINGS
,那么要屏蔽scanf() 函数的错误,代码中添加以下代码,要放到文件最上面就可以!
#define _CRT_SECURE_NO_WARNINGS
或者在VS中设置宏定义如图所示
-End-
最近有一些小伙伴,让我帮忙找一些 面试题 资料,于是我翻遍了收藏的 5T 资料后,汇总整理出来,可以说是程序员面试必备!所有资料都整理到网盘了,欢迎下载!
面试题
】即可获取