距离上次更新本文已经过去了 193 天,文章部分内容可能已经过时,请注意甄别

问题来源

当我们使用 vs 编译器编译 c 语言代码,并需要用到一些非常常用的库函数的时候(如 scanf)

vs 编译器通常会报出如下错误

报错

有的时候即便报错了,程序也可以正常运行。但有的时候就会同图中一样,程序无法运行!这时候就头大了。

出现这个错误的原因是 vs 编译器认为这些库函数是 “不安全的”(我可真谢谢你,担 duo 心 guan 那 xian 么 shi 多,微软)

解决方法

解决这个报错问题的方法有两种

1. 使用_s 函数

步骤

如图所示,我们可以在库函数后面加一个_s,这时候 vs 就会把它认为是 “安全的函数”,程序就可以正常运行了。

c
1
2
double m;
scanf_s("%lf",&m);

如下图所示,代码编译运行成功。

image.png

这个方法本质上是调用了 win 下 vs 重写过后的 scanf_s,因为是 vs 重写过后的,所以自然是安全的函数。

方法一的致命缺点

但是这么做有一个非常大的弊端:该代码只能在 vs 编译器里运行。

如图,如果我们将这一串带_s 的代码复制到 dev-c++ 这款编译器里面。devc++ 编译器会报错,无法运行这串代码!同样的,如果你需要在 mooc、牛客网或者其他刷题网站上填写代码的时候,系统也无法运行这种带了_s 的 c 语言代码。

这时候代码的 “可移植性” ,即通用性,就变差了!

image-20211025183853539

所以,解决方法二就登场了。

2. 使用防报错语句

步骤

只需要在这个源文件的第一行添加这样一串代码

c
1
#define _CRT_SECURE_NO_WARNINGS 1

这串代码的作用就是屏蔽掉 vs 编译器对函数危险性的排查报错。如图所示,我们的代码就能正常运行了,不会有告警和报错。

image.png

这样添加了之后,即便是将代码移植到另外一个编译器里,仍然能正常运行。因为在其他编译器中,这一个 define 什么作用都没有。只有在 VS 编译器中,这一行 define 会屏蔽掉不安全函数的检查,也就不会强制要求你使用_s 后缀的安全函数。

image.png

有的时候即便使用 scanf_s,还是会出现一些和 scanf 无关的奇怪报错。使用方法二就能彻底解决这个问题,所以建议大家还是使用方法二!

方法二的缺点?

你可能会想:那我岂不是每次写代码之前都需要打上这么一个 define 语句,那样也太麻烦了吧!再说了,这个语句这么长,我也背不下来啊!

别急,下面我就会告诉你怎么让 vs 编译器每次创建源文件的时候自动带上这么一串代码

如何在 vs 编译器里加上默认语句

这里我们需要用到另外一款同样很经典的软件,**Notepad++**。

如果你还没安装这款软件,这里是下载链接:点我

安装完成后,我们点击左上角的 文件 选项。

image-20211025185117420

打开 vs 的安装路径里,下图箭头所指的 newc++file 文件。

plaintext
1
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\VC\VCProjectItems

vs 编译器默认安装路径是 c 盘。如果你的 vs 编译器不在 c 盘,可以通过右键桌面 vs 编译器的快捷方式,打开文件所在的位置,找到你 vs 编译器的安装路径。

image-20211025185227485

该文件初次打开以后是空白的,我们只需要把这行 define 语句加入这个文件,ctrl+s 保存一下。由于 vs 编译器处于 c 盘,修改这个文件需要申请管理员权限,点击同意即可!

c
1
2
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

image-20211025185554124

修改了之后,你创建的新的 c 和 cpp 源文件,就会默认带上这串代码啦!

image.png

由于 <stdio.h> 这个头文件实在是太常用了,所以我把它也加入了这个文件里。这样就不用每次创建新的源文件的时候自己手打啦!

一劳永逸

结语

如果这篇文章对你有帮助的话,还请点个赞!万分感谢!