VS中C语言安全函数怎么回事?如何解决?

源码共读

共 2046字,需浏览 5分钟

 ·

2021-06-28 13:52

👇👇关注后回复 “进群” ,拉你进程序员交流群👇👇

作者丨李肖遥

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 StudioMicrosoft 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检查即安全性开发生命周期检查,我们而已手动取消。

  1. 菜单栏中选择设置如下图所示:
  1. 弹出一个对话框,选择“C/C++ --> SDL检查”,如下设置如下图所示:

_CRT_SECURE_NO_WARNINGS

开头的代码编译结果说到,请使用 _CRT_SECURE_NO_WARNINGS,那么要屏蔽scanf() 函数的错误,代码中添加以下代码,要放到文件最上面就可以!

#define _CRT_SECURE_NO_WARNINGS

或者在VS中设置宏定义如图所示

-End-

最近有一些小伙伴,让我帮忙找一些 面试题 资料,于是我翻遍了收藏的 5T 资料后,汇总整理出来,可以说是程序员面试必备!所有资料都整理到网盘了,欢迎下载!

点击👆卡片,关注后回复【面试题】即可获取

在看点这里好文分享给更多人↓↓

浏览 20
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报