• Scanf 不安全报错问题


    Scanf 不安全报错问题

    在这里插入图片描述


    每博一文案

    曾看过这样一个话题,一个人真的会忙到,没有时间回你的消息吗?
    评论区里最高赞的一条留言是,在这个手机不离身的年代里,
    没有谁会真忙到没时间去回复一条信息。
    等红灯的间隙,喝杯水的功夫,上厕所的空闲,
    爱你的人,会在百忙之中为你抽空。
    不爱你的人,总有推脱的借口,不得不承认被惦记,被理解,
    被爱护,一直都是人生三大幸事,可是最伤感的莫过于,
    你以为找到一个可以保护你的人,可是,后来的大风大浪都是他给的,
    很多时候,理智的放弃,胜过盲目的执着。
                                       ——————————————    一禅灵心庙语
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10


    • 相信大家在学习 C语言 中 使用我们的 VS 时一定遇到过下面的 报错问题吧,运行如下代码:
    #include<stdio.h>
    int main()
    {
    	int num = 0;
    	scanf("%d", &num);
    	printf("%d\n", num);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    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.
    
    • 1

    在这里插入图片描述


    • 其实上我们的 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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    运行结果

    在这里插入图片描述


    解析

    越界访问了,因为 scanf (不会关心你输入的数值,以及多少)输入之后,直接赋值,保存,这样就存在着越界,类型的不一致的问题出现,scanf 不会对空间越界上的判断,以及类型是否合适的判断好,所以被 VS 认为是不安全的


    解决方案

    方案一

    • 使用预处理的方式:解决

    • 我们仔细阅读错误的提示信息,我们不难发现,提示信息是这样的

    scanf 函数是不安全的,考虑使用 scanf_s 来替换,如果不想看到错误,也可以使用 _CRT_SECURE_NO_WARNINGS

    在这里插入图片描述


    • 我们可以在你使用不安全的函数的源文件(.c)的 最开头 第一行注意 一定是第一行加上这么一句 预定义
    #define  _CRT_SECURE_NO_WARNINGS  1
    
    • 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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    运行结果 我们是可以发现是不存在报错的问题的,编译生成成功了

    在这里插入图片描述


    • 那么是不是,我们每次在使用 不安全的函数的时候,都需要写这样一句话呢!—— 答案: 是的,但我们有一个一劳永逸的方法 —— 就是在每次新建文件的时候,都会自动附加上这样一句 预处理 ,怎么做呢!,操作如下:
    • 首先 我们需要在 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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运行结果 也是没有问题的

    在这里插入图片描述


    方案二

    • 我们设置该项目的属性 如图:我们点击解决方案资源管理器 ,使用鼠标 右击 我们的 项目名称 ——> 点击属性

    在这里插入图片描述


    • 弹出如下窗口 我们依次点击 ——> 配置属性 ——> c/c++ ——> 预处理,中找到 预处理定义;

    在这里插入图片描述


    • 最后我们在 预处理定义中 加上我们方案一使用的预处理:**;_CRT_SECURE_NO_WARNINGS ** 注意 一定要使用 分号 隔开的不然会出问题的,点击应用——> 再确定一下 就好了

    在这里插入图片描述


    运行结果 同样是没有问题的

    在这里插入图片描述


    • 这里我介绍了,两种方案,其实上我还有一种方案,但是那种方案不太好,我就不介绍了
    • 这两种方案,大家喜欢,那种呢,我个人还是比较喜欢第一种方案,因为它是从 C90 中语法的角度解决的,另一种是从 VS编译器 的角度解决的

    最后:

    限于自身水平,其中存在的错误希望大家,给予指教,韩信点兵 —— 多多益善,谢谢大家!,后会有期,江湖再见!

  • 相关阅读:
    TCP/IP(十七)实战抓包分析(一)ICMP
    [4G/5G/6G专题基础-155]: 5G 3GPP高精确室内定位原理、AI方案概述
    【无标题】
    解决 @RefreshScope 导致定时任务注解 @Scheduled 失效
    PostgreSQL的学习心得和知识总结(一百一十一)|内核级自上而下完美实现PostgreSQL数据库 日志格式tsvlog 的实现方案
    代码随想录算法训练营二十四期第十天|LeetCode232. 用栈实现队列、LeetCode225. 用队列实现栈
    (idea版本)下载javaFX和配置环境详细大全
    系统分析师备考经验分享:分阶段、分重点
    OmniShade - Mobile Optimized Shader
    Java 注解与反射
  • 原文地址:https://blog.csdn.net/weixin_61635597/article/details/125629709