Scanf 不安全报错问题
每博一文案
曾看过这样一个话题,一个人真的会忙到,没有时间回你的消息吗?
评论区里最高赞的一条留言是,在这个手机不离身的年代里,
没有谁会真忙到没时间去回复一条信息。
等红灯的间隙,喝杯水的功夫,上厕所的空闲,
爱你的人,会在百忙之中为你抽空。
不爱你的人,总有推脱的借口,不得不承认被惦记,被理解,
被爱护,一直都是人生三大幸事,可是最伤感的莫过于,
你以为找到一个可以保护你的人,可是,后来的大风大浪都是他给的,
很多时候,理智的放弃,胜过盲目的执着。
—————————————— 一禅灵心庙语
- 相信大家在学习 C语言 中 使用我们的 VS 时一定遇到过下面的 报错问题吧,运行如下代码:
#include<stdio.h>
int main()
{
int num = 0;
scanf("%d", &num);
printf("%d\n", num);
return 0;
}
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.
- 其实上我们的 VS 不仅仅只是 对于 scanf 的不安全支持 还有
- strcpy
- strcat
- sscanf
- fopen
- …
- 等等这些都被 vs 认为是不安全的
为什么会提示不安全
- 请看如下代码:
#include<stdio.h>
int main()
{
char arr[6] = { 0 };
scanf("%s", &arr);
printf("%s\n", arr);
return 0;
}
运行结果
解析
越界访问了,因为 scanf (不会关心你输入的数值,以及多少)输入之后,直接赋值,保存,这样就存在着越界,类型的不一致的问题出现,scanf 不会对空间越界上的判断,以及类型是否合适的判断好,所以被 VS 认为是不安全的
解决方案
方案一
-
使用预处理的方式:解决
-
我们仔细阅读错误的提示信息,我们不难发现,提示信息是这样的
scanf 函数是不安全的,考虑使用 scanf_s 来替换,如果不想看到错误,也可以使用 _CRT_SECURE_NO_WARNINGS
- 我们可以在你使用不安全的函数的源文件(.c)的 最开头 第一行 ,注意 一定是第一行加上这么一句 预定义
#define _CRT_SECURE_NO_WARNINGS 1
- 我们运行一下加入这行代码后,是否还存在报错的问题:
#define _CRT_SECURE_NO_WARNINGS 1 // 放在第一行,
#include<stdio.h>
int main()
{
char arr[6] = { 0 };
scanf("%s", &arr);
printf("%s\n", arr);
return 0;
}
运行结果 我们是可以发现是不存在报错的问题的,编译生成成功了
- 那么是不是,我们每次在使用 不安全的函数的时候,都需要写这样一句话呢!—— 答案: 是的,但我们有一个一劳永逸的方法 —— 就是在每次新建文件的时候,都会自动附加上这样一句 预处理 ,怎么做呢!,操作如下:
- 首先 我们需要在 VS 的安装路径中找到一个名为 newc++file.cpp 的文件
- 我们使用一个软件名为Notepad++ 的文本编辑器下载链接:🔜🔜🔜 Notepad++ ,之所以使用该文本编辑器是因为,如果你使用普通的记事本打开,无法在该文件中保存住内容的(就是你点击的保存,但是当你再次打开该文件的时候会发现其实并没有保存到的),所以我们才需要它的
- 下载好后,我们使用该软件打开它 :
- 我们在其中添加我们所需要的 预处理符号 : #define _CRT_SECURE_NO_WARNINGS 1
- Ctrl + s 一下,保存一波,就可以了
- 这样我们每次新建的项目都会自动为我们添加上该 预处理了
- 这里解释一下,我们为什么不使用 scanf_s 的原因
因为 scanf_s 函数是由,微软中的 VS编译器 提供的,仅仅是在 微软 中支持的,在其他地方是不支持的,就是说,如果你的代码放在 gcc编译器 中编译,就会报错,因为它不认识 微软的这个 scanf_s 函数的,这样你的代码就不具有跨平台性了,而且 scanf 的使用方式和 scanf_s 函数的使用也又一定的区别:
而使用预处理 : #define _CRT_SECURE_NO_WARNINGS 1 是 C90 语法支持的
- 同样根据 C90 的语法:我们还有一种解决方式:就是
在头文件的下面,main 方法的前面加上: #pragma warning (disable:4996) 也是可以的
#pragma warning (disable:4996)
int main()
{
char arr[6] = { 0 };
scanf("%s", &arr);
printf("%s\n", arr);
return 0;
}
运行结果 也是没有问题的
方案二
- 我们设置该项目的属性 如图:我们点击解决方案资源管理器 ,使用鼠标 右击 我们的 项目名称 ——> 点击属性
- 弹出如下窗口 我们依次点击 ——> 配置属性 ——> c/c++ ——> 预处理,中找到 预处理定义;
- 最后我们在 预处理定义中 加上我们方案一使用的预处理:**;_CRT_SECURE_NO_WARNINGS ** 注意 一定要使用 分号 隔开的不然会出问题的,点击应用——> 再确定一下 就好了
运行结果 同样是没有问题的
- 这里我介绍了,两种方案,其实上我还有一种方案,但是那种方案不太好,我就不介绍了
- 这两种方案,大家喜欢,那种呢,我个人还是比较喜欢第一种方案,因为它是从 C90 中语法的角度解决的,另一种是从 VS编译器 的角度解决的
最后:
限于自身水平,其中存在的错误希望大家,给予指教,韩信点兵 —— 多多益善,谢谢大家!,后会有期,江湖再见!