【C/C++】VS2017提示函数scanf不安全

问题描述: 

在使用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上编程)

如果只使用VS编写代码,那么还是使用函数scanf_s比较好,毕竟安全可靠,而且使用难度也没大很多。

方法二 (假设不止使用VS编程)

如果编写的代码需要移植到其他IDE上,由于函数scanf_s是VS特有的,其他IDE将不认识这个函数,从而报错。如果在VS上仍希望使用函数scanf,可以采取以下3种手段。

一  在VS上编程时,第一行首先写上如下语句。

#define _CRT_SECURE_NO_WARNINGS

此后,可正常使用函数scanf。系统将不会报错。如下代码。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> 

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++,找到代码生成,在代码生成中有个安全检查,将启用安全检查修改为禁用安全检查。这个方法也行。

  • 19
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桂哥317

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值