Visual Studio编辑器中C4996 ‘scanf‘: This function or variable may be unsafe.问题解决方案

目录

​编辑

题目:简单的a+b

1.  题目描述

2.  输入格式

3.  输出格式

4.  样例输入

5.  样例输出

6.  解题思路

7.  代码示例

8.  报错解决

方案一

方案二

方案三

方案四

总结


题目:简单的a+b

1.  题目描述

输入两个整数a和b,计算a+b的和

本题很简单,但是注意此题是多组测试数据,即需要不停的接收系统的测试输入,你都可以计算结果并输出

2.  输入格式

输入两个整数A和B

范围不超过2^10

3.  输出格式

求A+B

4.  样例输入

1 1
10 20

5.  样例输出

2
30

6.  解题思路

首先,本题的首要条件是“需要不停的接收系统的测试输入,你都可以计算结果并输出”

我们可以通过while循环,不断地输入数据,进行条件判断执行

注:while(表达式){若干语句}//循环语句及其格式,若表达式里的语句成立,执行若干语句

而如何进行输入,就需要用到scanf语句

注:scanf("输入模式",地址列表);//输入语句及其格式。注:地址列表一定要加取地址符号&,如:&a,&b

而输入完对于输入语句的计算以及输出,我们可以直接在printf里执行

注:printf("输出模式",输出列表);//输出语句及其格式。注:输出模式和输出列表一一对应,如:printf("%d%d",a,b);

7.  代码示例

#include<stdio.h>
int main()
{int a=0,b=0;while(~scanf("%d%d", &a, &b))   {printf("%d\n",a+b);}    return 0;
}

想要退出循环,按下Ctrl+Z,回车才会退出循环,可能需要多循环几次

其中需要注意的一点是,在Visual Studio编辑器中可能会出现报错

'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.	Project16	D:\Visual Studio\project\Project16\Project16\FileName.cpp	5	

8.  报错解决

这里我们有两种解决方案:

方案一

将scanf改为scanf_s

#include<stdio.h>
int main()
{int a = 0, b = 0;while (~scanf_s("%d%d", &a, &b))   {printf("%d\n", a + b);}return 0;
}

        将 scanf 函数改为 scanf_s 函数的作用是增加输入的安全性,防止发生缓冲区溢出的问题。scanf_s 是 Microsoft 提供的安全版本的输入函数,相比于 scanf,它会在读取数据时进行一些额外的检查,并限制输入的字符数量。

        使用 scanf 函数时,如果输入的数据长度超过了目标变量所能容纳的大小,就可能导致缓冲区溢出,造成安全隐患。而 scanf_s 函数在读取数据时,可以指定目标变量所能接收的最大字符数量,从而避免缓冲区溢出的情况。

scanf_s 的函数签名如下:

int scanf_s(const char *format, ...);

        与 scanf 不同的是,scanf_s 在读取字符串时需要指定字符串的最大长度,以确保输入不会超出缓冲区的大小。比如,使用 scanf_s 读取一个字符串时,可以这样写:

char str[20];
scanf_s("%19s", str, sizeof(str));

        在上述代码中,限定了输入的字符串长度最多为 19 个字符(因为数组大小是 20,还要留一个字符给字符串结尾的空字符)。这样做可以防止用户输入超过目标变量所能容纳的字符数量。

        总之,通过使用 scanf_s 函数,我们可以增加输入操作的安全性,防止发生缓冲区溢出的问题。然而,需要注意的是,scanf_s 是 Microsoft 特定的函数,在其他编译器中可能不被支持。因此,在使用 scanf_s 时应该注意兼容性问题。

方案二

在代码最上方加:

#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>int main()
{int a = 0, b = 0;while (~scanf("%d%d", &a, &b))   {printf("%d\n", a + b);}return 0;
}

        记住一定是在代码的最上方加,否则依旧报错,因为预处理指令是在编译器开始编译之前执行的。而编译器是按照源代码的顺序逐行读取和编译代码的,因此如果 #define _CRT_SECURE_NO_WARNINGS 放在其他代码之后,那么编译器可能会在处理到某些不安全的函数时已经发出了警告信息,从而无法起到禁用警告的效果。

   #define _CRT_SECURE_NO_WARNINGS 是一条预处理指令(preprocessor directive),在 C 语言编程中常用于禁用特定编译器警告信息。

        在 Microsoft Visual Studio 编译器中,使用一些被认为不安全的函数(如 fopenscanf 等)时,编译器会发出警告。这些警告是为了提醒开发者使用更安全的函数或者采取更安全的方法,以避免潜在的安全问题(如缓冲区溢出)。

        然而,在某些情况下,我们可能需要继续使用这些被标记为不安全的函数,例如在旧代码的迁移过程中或者与其他平台进行兼容性开发时。此时,#define _CRT_SECURE_NO_WARNINGS 可以用来禁用这些特定警告,使得编译器不再产生相关的警告信息。

        通过包含该预处理指令,我们告诉编译器不要发出与安全问题相关的警告,这样在编译时就不会看到相关的警告信息了。但需要注意的是,禁用这些警告并不会改变函数的行为,因此在使用这些函数时仍然需要谨慎确保输入的安全性。

        需要强调的是,禁用编译器警告可能会导致潜在的安全问题被忽略,因此在使用 #define _CRT_SECURE_NO_WARNINGS 时需要权衡利弊,并尽可能采取更安全的函数或方法来处理相应的问题。

方案三

在代码最上方加:

#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>int main()
{int a = 0, b = 0;while (~scanf("%d%d", &a, &b))   {printf("%d\n", a + b);}return 0;
}

        放到最上方的原因同方案二

  #define _CRT_SECURE_NO_DEPRECATE 是一条预处理指令(preprocessor directive),在 C 语言编程中常用于禁用某些特定函数的警告信息,具体来说,它可以用来避免使用已经被VS 标记为不安全的函数时产生的编译器警告。

        例如,在使用 fopen 函数时,如果不使用 _CRT_SECURE_NO_DEPRECATE,则可能会出现类似以下的编译器提示:

warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead.

        这是因为在Visual Studio中,许多标准 C 库函数被认为是不安全的,因为它们可能会受到缓冲区溢出等安全问题的影响。因此,为了更好地保护程序的安全性,Microsoft 建议使用相应的安全函数替代这些不安全的函数。

        然而,对于一些旧的代码或者遗留系统,可能难以修改所有不安全函数的调用。在这种情况下,我们可以使用 _CRT_SECURE_NO_DEPRECATE 来禁用编译器警告,从而继续使用这些不安全的函数。

        需要注意的是,使用 _CRT_SECURE_NO_DEPRECATE 可能会降低程序的安全性,因此在使用时要谨慎权衡利弊,并尽可能使用更安全的函数或方法来处理相应的问题。

方案四

在代码上方加:

#pragma warning(disable:4996)
#pragma warning(disable:4996)
#include<stdio.h>int main()
{int a = 0, b = 0;while (~scanf("%d%d", &a, &b))   {printf("%d\n", a + b);}return 0;
}

   #pragma warning(disable:4996) 是一条预处理指令(preprocessor directive),用来禁用编译器产生与函数安全问题相关的警告信息。这个警告通常出现在使用一些被标记为不安全的函数时,例如 scanfstrcpy 等。警告的代码是 C4996

        在 Visual Studio 中,这些函数通常被标记为不安全,因为它们可能导致缓冲区溢出等安全问题。因此,编译器会发出警告信息,提醒开发者使用更安全的函数或方法。

        但是,在某些情况下,我们需要继续使用这些被标记为不安全的函数,例如在旧代码的迁移过程中或者与其他平台进行兼容性开发时。此时,#pragma warning(disable:4996) 可以用来禁用这个特定的警告,使得编译器不再产生相关的警告信息。

        通过包含该预处理指令,我们告诉编译器不要发出与安全问题相关的警告,这样在编译时就不会看到相关的警告信息了。但需要注意的是,禁用这些警告并不会改变函数的行为,因此在使用这些函数时仍然需要谨慎确保输入的安全性。

        需要注意的是,#pragma warning(disable:4996) 只是针对 Visual Studio 编译器有效,如果使用其他编译器,可能需要使用不同的预处理指令或者参数。

        总之,#pragma warning(disable:4996) 用于禁用与函数安全问题相关的警告,可以帮助我们在某些情况下继续使用被标记为不安全的函数。但是,禁用编译器警告可能会导致潜在的安全问题被忽略,因此在使用 #pragma warning(disable:4996) 时需要权衡利弊,并尽可能采取更安全的函数或方法来处理相应的问题。

总结

方案一:将scanf改为scanf_s

方案二:在代码最上方加:#define _CRT_SECURE_NO_WARNINGS

方案三:在代码最上方加:#define _CRT_SECURE_NO_DEPRECATE

方案四:在代码上方加:#pragma warning(disable:4996)

简单来说,编译器看不到错我,我就是对的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/277694.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

海思平台isp之raw图回灌调试

文章目录 一、搭建环境二、配置参数三、回灌raw图isp调试中,经常会遇到一些特定场景的效果需要优化,但由于某些原因和成本考虑,开发人员无法亲临现场,这个时候采集场景raw图回灌到板端调试,就显得尤为方便了。 一、搭建环境 (1)建立板端与PQTool连接 板端进入SS928V100…

深圳锐科达IP网络广播系统

深圳锐科达IP网络广播系统 网络音频广播系统是一种基于TCP/IP网络的纯数字音频广播系统。该网络音频广播系统在物理结构上与标准IP网络完全集成。它不仅真正实现了基于TCP/IP网络的数字音频的广播、直播和点播&#xff0c;而且利用TCP/IP网络的优势&#xff0c;突破了传统模拟广…

Ubuntu20.04 下编译安装 ffmpeg 和 ffplay

Ubuntu20.04 下编译安装 ffmpeg 和 ffplay 一、下载源码包二、安装依赖库三、编译四、添加环境变量五、验证是否成功六、问题 一、下载源码包 1.1 官方下载链接&#xff1a;http://ffmpeg.org/download.html 最新版本为6.1&#xff0c;点击 Download Source Code下载即可 &…

AWTK 串口屏开发(2) - 数据绑定高级用法

AWTK 串口屏 智能家居示例 1. 功能 这个例子稍微复杂一点&#xff0c;界面这里直接使用了 立功科技 ZDP1440 HMI 显示驱动芯片 例子中的 UI 文件和资源&#xff0c;重点关注数据绑定。在这里例子中&#xff0c;模型&#xff08;也就是数据&#xff09;里包括一台空调和一台咖…

RF模块是如何工作的?

射频&#xff08;RF&#xff09;模块使用无线电频率工作&#xff0c;这个频率范围在30kHz到300kHz之间变化。 在这个射频系统中&#xff0c;数字数据被表示为载波波幅度的变化。这种调制类型是振幅移位键。 这个射频模块是射频发射器和接收器的组合&#xff0c;发射器接收器对的…

安装ubuntu虚拟机并连接xShell+安装MySQL

网盘地址 链接&#xff1a;https://pan.baidu.com/s/1r-Je09AJrZcmbPYnCI6rfA?pwdk22h 提取码&#xff1a;k22h 安装 打开Vmware 一直下一步就行了 xshell连接 打开虚拟机&#xff0c;右键进入Terminal终端&#xff0c; 只复制opubuntu:~$后面的语句&#xff0c;前面op代…

如何使用蜘蛛池蚂蚁SEO

​蜘蛛池是一种利用搜索引擎爬虫进行推广营销的方式。它的核心是建立一个能够吸引搜索引擎爬虫的网站群&#xff0c;这些网站能够产生大量的优质内容&#xff0c;并形成一个巨大的网站群&#xff0c;从而吸引更多的搜索引擎爬虫。 如何联系蚂蚁seo&#xff1f; baidu搜索&…

算法基础概念之数据结构

邻接表 每个点作为头节点接一条链表 链表中元素均为该头节点指向的点 优先队列 参数: ①储存元素类型 ②底层使用的存储结构(一般为vector) ③比较方式(默认小于)

spring-cloud-stream-kafka生产速度慢

包版本spring-cloud-starter-stream-kafka:3.1.0 修改yaml配置 添加poller配置

为什么全局变量可能成为多线程环境中的安全隐患

目录 全局变量的概念和特性 多线程环境下的问题 1. 竞争条件&#xff08;Race Condition&#xff09; 2. 内存一致性&#xff08;Memory Consistency&#xff09; 3. 死锁&#xff08;Deadlock&#xff09; 如何降低全局变量带来的安全隐患 1. 局部化数据 2. 合理使用锁…

黑马点评05分布式锁 1互斥锁和过期时间

实战篇-09.分布式锁-基本原理和不同实现方式对比_哔哩哔哩_bilibili 1.分布式锁 因为jvm内部的sychonized锁无法在不同jvm之间共享锁监视器&#xff0c;所以需要一个jvm外部的锁来共享。 2.redis setnx互斥锁 加锁解锁即可 2.1不释放锁可能死锁 redis 的setnx不会自动释放锁…

wpf devexpress如何使用AccordionControl

添加一个数据模型 AccordionControl可以被束缚到任何实现IEnumerable接口的对象或者它的派生类&#xff08;例如IList,ICollection&#xff09; 如下代码例子示范了一个简单的数据模型使用&#xff1a; using System.Collections.Generic;namespace DxAccordionGettingStart…