问题描述:
????????使用VS编辑器编写C语言代码时,调用scanf()函数输入内容时候报错。
错误代码:C4996
?????????
?问题原因:
??????? VS编译器认为直接使用C语言定义的函数scanf()不检查边界,不安全。scanf()等函数存在于版本较旧的CRT(C runtime library, part of the C standard library)中,具有安全性问题,比如在读取字符时,若不指定%s的宽度,可能会导致缓冲区溢出。
解决办法:
- 一、改用scanf_s()函数
- 使用VS编译器所提供的包括 scanf_s、wscanf_s等以_s结尾版本的函数具有安全增强功能。直接将VS编译器中的scanf()函数后加入_s即可。该方法对于已经习惯调用scanf()函数的朋友们来说,属于是治标不治本。
- 举一个栗子方便大家理解:自己的写的代码相当于货物,scanf()函数是货物里面的一部分,但该部分在其安检部门(SDL检查)看来是不安全的,因此货物无法通过,但scanf_s函数在安检部门看起来是安全的,就可以顺利通过。
- 二、找到并关闭VS中的SDL检查
- 右键“项目文件” — “属性” — “配置属性” — “C/C++”— “常规”— “SDL检查”改为“否”即可
- 这个只针对于该项目,关闭了本次项目的SDL检查(安全开发周期检查)。关闭SDL检查相当于绕过安监部门(SDL检查),直接出货。
- 三、在程序开通使用pragma命令
-
#pragma warning(disable:4996) 将一个warning作为一个错误
或者
#pragma warning(once:4996) 将一个warning禁用掉 - 这里需要注意pragma命令只对当前文件有效(对于.h,对包含它的cpp也是有效的),而不是对整个项目的所有文件有效。当该文件编译结束,设置也就失去作用。
- 可以理解为只有这一个货物在通过安检部门(SDL检查)的时候耍流氓,所以顺利通过。
- 补充说明pragma函数:
-
#pragma warning(push) 存储当前报警设置。
#pragma warning(push, n) 存储当前报警设置,并设置报警级别为n。n为从1到4的自然数。
#pragma warning(pop) 恢复之前压入堆栈的报警设置。
在一对push和pop之间作的任何报警相关设置都将失效。
#pragma warning(disable: n) 将某个警报置为失效
#pragma warning(default: n) 将报警置为默认
某些警告如C4309是从上到下生效的。即文件内#pragma warning从上到下遍历,依次生效。
- 四、更改头文件,添加宏定义
- 将#define _CRT_SECURE_NO_WARNINGS宏定义置于源文件的顶部,来忽略警告问题,此方法属于这一批货物都耍流氓,对其忽略,所以也可以通过。
- 也可以在编译器内部的预定义进行修改:右键“项目文件” — “属性” — “配置属性” — “C/C++”— “预编译器”— “预编译器定义”添加“”即可
- 也可以修改VS编译器安装路径下的“newc++file.cpp”文件,该方法有一定风险,此处不再展开,有需要的小伙伴可以自行搜索。
|