C语言杂谈(一)scanf()、scanf_s()与错误 C4996

错误 C4996

初学C语言时,第一个接触到的I/O函数便是scanf()了。但在高版本的 Visual Studio (包括但不限于2015、2013、2012)编译代码时,却会出现意想不到的错误。
有如下一段简单的代码:

#include "stdio.h"
int main(void)
{
    int i;
    printf("Input i\n");
    scanf("%d", &i);
    printf("i is %d", i);
    return 0;
}

但会输出一个错误 C4996,错误信息如下

错误 1 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.

报错说scanf不安全,推荐将scanf替换scanf_s。替换之后之后,代码如下

#include "stdio.h"
int main(void)
{
    int i;
    printf("Input i\n");
    scanf_s("%d", &i);
    printf("i is %d", i);
    return 0;
}

便没有错误提示了。

scanf与scanf_s

在MSDN有介绍这些以_s结尾的函数,包括 scanf_s、scanf_s_l、wscanf_s、_wscanf_s_l。这些版本的函数具有安全增强功能。

scanf等函数存在于版本较旧的CRT(C runtime library, part of the C standard library)中,具有安全性问题,比如在读取字符时,若不指定%s的宽度,可能会导致缓冲区溢出。

在使用scanf时,如果规定了读取的宽度,便不会报错。将代码修改如下:

#include "stdio.h"
int main(void)
{
    int i;
    printf("Input i\n");
    scanf_s("%5d", &i);
    printf("i is %d", i);
    return 0;
}

这里控制了读入的%d宽度为5。但是读入的数据超过宽度的限制时,便会丢失数据。比如这是输入100000,输出的i值为10000。

解决方法

1.使用scanf时规定宽度。

2.使用sacnf_s替换sacnf。

3.在新建项目的时候取消SDL检查。

时间: 2024-08-06 02:03:39

C语言杂谈(一)scanf()、scanf_s()与错误 C4996的相关文章

C语言格式化之scanf

1.       格式输入函数的一般形式 函数功能:用于接收从键盘上输入的数据,输入的数据可以是整型.实型和字符型等. 一般形式:scanf(“格式控制字符串”,变量地址列表): 格式控制字符串:用于控制输入数据格式,必须以引号引导,内容由一个或多个格式控制字符组合而成,也可以含有非格式控制字符,非格式控制字符称为普通字符.普通字符按原样在对应位置输入. 变量地址列表:用于指定存放数据的变量地址.如果需要给多个变量输入数据,则各变量地址要用逗号隔开.变量地址表示方式是:&变量名.例如,&a

vs2013/2015中scanf函数类似于error C4996: 'scanf': This function or variable may be unsafe的安全检查错误

在使用vs2015时,遇到了scnaf函数安全性的问题,程序不能正常运行,错误如下: 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. 经调试,发现这个错误的原因是:scanf等类似的函数已经不太

SCANF SCANF_S

今天在看C的教程的时候,用VS2013写了一小段代码 scanf("%f",&w); 提示需要在预编译器里添加 _CRT_SECURE_NO_WARNINGS,  百度了下,发现要么用 scanf_s 来代替scanf,要么就添加这个定义 原因是,VS针对scanf的不安全性,又包了一个scanf_s的函数 ,定义里,多了一个长度的参数, scanf_s("%s",buf,sizeof(buf)); 这样不会导致内存溢出错误(比如只能接受4个长度的数组,输入

【C】将m~n之间的素数输出与VS2005以上版本对C语言的scanf的警告warning C4996

素数也叫质数,就是在大于1的自然数中,除了1和此整数自身外,不能被其他不包括0的自然数所整除的数, 需要注意的是,判断一个自然数n是否为质数,无须从1-n检验是否都能与此数整数,只需要用少于等于根号n的所有素数与此数试除即可,这样,每个数的检验的时间复杂度,足足减少了一半. C语言的实现代码如下: #include<stdio.h> #include<math.h> void main(){ int m,n; printf("输出从m到n的素数:\n"); pr

C++ 的语言杂谈(一)--C++不是新手友好的

C++的语言品味是独特的,喜欢的人特别喜欢,讨厌的人特别讨厌.虽然Bjane Stroustrup不断地宣称C++的发展方向是新手友好的,但实际上对新手来说,最重要的还是有强大方便的标准库可以使用(像Java/C#/Python之类),让程序员们可以迅速地完成手头的工作.Bjane Stroustrup本人也看到这个问题,并经常强调强加标准库的重要性,不过好像标准委员会并没有太理会这个事,大部的提案都是围绕语言核心的. 偶尔地想了一下这个事,为什么会这样呢? 原因就是标准会从来就没有认真考虑过新

C语言打印输出,scanf使用注意事项,小技巧

 今天看一帖子,赵忠大哥的回复挺经典也很有用,记录下来! 1.在每个最后不带\n的printf后面加fflush(stdout); 2.在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin);另外请检查scanf的返回值. 3.在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题. C语言打印输出,scanf使用注意事项,小技巧

C语言中关于scanf函数的用法

scanf()函数的控制串 函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化输入函数,它从标准输入设备(键盘) 读取输入的信息.可以读入任何固有类型的数据并自动把数值变换成适当的机内格式. 其调用格式为: scanf("<格式化字符串>",<地址表>); scanf()函数返回成功赋值的数据项数,出错时则返回EOF. 其控制串由三类字符构成

scanf()常犯错误

------------------------------------------------------------------------ <1> 本意:接收字符串. 写成代码:void main() { char *str; scanf("%s",str); printf("string is: %s\n",str); } 符合愿意代码:char *str=NULL; str=malloc(128*sizeof(char) ); scanf( &

windows phone 切换多语言时,商店标题显示错误的问题

前段时间,用业余时间写了一款 wp8 app(“超级滤镜”商店,中文地址:英文地址),在多语言的时候,给 app title 和 app tile title 进行多语言时(参考 MSDN),中文商店(zh-cn)总是显示 “Super Imaging” 而不是 “超级滤镜”, 但是在手机上切换多语言时,名称显示正确,所以猜测是清单文件 WMAppManifest.xml 配置错误. 默认情况下,把英语作为 app 的显示语言,设置如下: 1.右键单击项目属性,单击 “程序集信息”: 2.在“非