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 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  ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧

推荐阅读:


嵌入式编程专辑
Linux 学习专辑
C/C++编程专辑
Qt进阶学习专辑

关注我的微信公众号,回复“加群”按规则加入技术交流群。


点击“阅读原文”查看更多分享。