在使用VS2017编写代码时,出现如下错误:
error 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 这个函数或者变量可能不安全。建议考虑使用函数scanf_s。为了不显示弃用说明(应该指的这个错误提示),可以使用_CRT_SECURE_NO_WARNINGS。详情见在线帮助。
函数scanf是ANSI C中的函数,其在读取时不检查边界,所以可能造成内存访问越界。例如分配了5个字节的空间,但读入了10个字节,如下:
char buf[5] = {'\0'};
scanf("%s", buf);
如果输入1234567890,则567890会被写到别的空间上去,从而导致程序运行异常。
有时黑客可以利用函数scanf 的这个不安全性黑掉系统。为了防止这一问题,从VC++2005开始,微软公司的VS提供了函数scanf_s。其功能与原版函数scanf 相同,不同的是,在调用函数scanf_s时,必须提供一个数字以表明最多读入多少位字符。
以上代码如果用函数scanf_s,则第二行应改为:
scanf_s("%s", buf, 5);
表示最多读取4个字符,因为buf[4]要放'\0'。函数scanf_s的最后一个参数n是缓冲区的大小,表示最多读取n-1个字符。采用函数scanf_s读取单个字符时,也需要限定长度,写法如下。
scanf_s("%c, %c", &c1, 1, &c2, 1);
总结一下,函数scanf是原版的输入函数,函数scanf_s是微软公司VS特有的函数。两者功能相同,只是后者更安全可靠。
如果只使用VS编写代码,那么还是使用函数scanf_s比较好,毕竟安全可靠,而且使用难度也没大很多。
如果编写的代码需要移植到其他IDE上,由于函数scanf_s是VS特有的,其他IDE将不认识这个函数,从而报错。如果在VS上仍希望使用函数scanf,可以采取以下3种手段。
一 在VS上编程时,第一行首先写上如下语句。
#define _CRT_SECURE_NO_WARNINGS
此后,可正常使用函数scanf。系统将不会报错。如下代码。
#define _CRT_SECURE_NO_WARNINGS
#include
int main(void)
{
int x;
scanf("%d", &x);
printf("%d\n", x);
system("pause");
return 0;
}
二 如果不想在第一行输入该语句,也可以在VS的项目属性中进行配置,这样,在整个项目中都可以正常使用函数scanf。配置的步骤如下:
1. 找到菜单栏的项目→项目的属性→C/C++→预处理器
2. 右侧有个预处理器定义,在其参数中加上 _CRT_SECURE_NO_WARNINGS,如下图。
这样,在编译器进行预处理时,预处理器就会自动地在程序开头添加我们需要的宏定义,而不再需要我们手动添加。在文件中不添加宏定义的情况下,再次进行编译,可以编译成功。这种方案因为修改的是项目的配置参数,因此适用于整个项目。在该项目中,将不再需要添加相关宏定义。但是其他项目自然不受该设置的影响,因此,如有需要,在其他项目中需要再次进行相同的配置才能生效。
三 如果还是觉得上述2种手段麻烦的话,还有第3种手段。找到菜单栏的项目,找到项目的属性,找到C/C++,找到代码生成,在代码生成中有个安全检查,将启用安全检查修改为禁用安全检查。这个方法也行。