关于vs中scanf函数的一点说明

来源:互联网 发布:高二数学算法初步 编辑:程序博客网 时间:2024/04/29 10:05
众所周知,由于安全原因,vs2012版本及其以上会出现scanf函数报错的情形,编译时便会提示如下错误:

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.


错误解释:

微软该种类型报错主要因为那些C库的函数,很多函数内部是不进行参数检测的(包括越界类的),微软担心使用这些会造成内存异常,所以就改写了同样功能的函数,改写了的函数进行了参数的检测,使用这些新的函数会更安全和便捷。关于这些改写的函数你不用专门去记忆,因为编译器对于每个函数在给出警告时,都会告诉你相应的安全函数,查看警告信息就可以获知,在使用时也再查看一下MSDN详细了解。


一般来说,直接解决该问题方法有三种:

方法一:将原来的旧函数替换成新的 Security CRT functions,即替换成为新的函数scanf_s,但是scanf_s函数比scanf函数多了一个参数,即读取个数参数。例如scanf从输入流中读取一个字符类型字节,scanf("%c",&ch),则若使用scanf_s需改为scanf_s("%c",&ch,1);


方法二:以下方法的原理为屏蔽这个错误:

              1. 在预编译头文件stdafx.h里(注意:一定要在没有include任何头文件之前)定义下面的宏:

                    #define _CRT_SECURE_NO_DEPRECATE

              2. 或声明 #param warning(disable:4996)

              3. 更改预处理定义:

                  项目->属性->配置属性->C/C++ -> 预处理器 -> 预处理器定义,增加:

                 _CRT_SECURE_NO_DEPRECATE

                 第三种注意更改预处理定义时若在最后面加上该句话,需在这句话前面即未加之前最后面加上一个分号(在英文输入法模式下哦~)。


方法三:方法二没有使用更加安全的 CRT 函数,显然不是一个值得推荐的好方法,但我们又不想一个一个地改函数名,这里还有一个更简便的方法:

                在预编译头文件 stdafx.h 里(同样要在没有include任何头文件之前)定义下面的宏:

                #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1

                在链接的时候便会自动将旧函数替换成 Security CRT functions 。

               注意:这个方法虽然使用了新的函数,但是不能消除警告(原因见红字),你还得同时使用方法二(-_-)。即实际应在预编译头文件 stdafx.h 里加入下面两句:

                           #define _CRT_SECURE_NO_DEPRECATE

                           #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1


虽然解决了该报错问题,但是很多童鞋会发现运行时,scanf函数虽然并未报错,即该程序正确执行,但是在输入时,会发现scanf函数跳过输入字符的原因,即你没有办法输入的问题,这是为什么呢?

因为scanf只是读入一个字符,而你在输入时实际上输入的是:字符+回车(Enter),Enter产生的"\n"也在输入缓冲区中,下次调用 scanf时就会直接读到 它而不是等待你再次输入!所以我们不提倡使用 scanf("%c", ...),特别是不提倡把它用在循环中。这也是微软改写该类函数的原因,那么如何解决呢?


一把来说,主要方法有四种:


方法一:只要再加一句scanf就行了。


方法二:使用函数fflush,清除流,就是在每个接收字符的scanf语句前面,加上fflush(stdin);


方法三:将 scanf("%c", &ch); 修改为:     scanf(" %c", &ch);    /*在%前加上一个空格*/


方法四:将 scanf("%c", &ch); 修改为:     scanf("%c%*c", &ch);   %*c是跳过一个输入字符的意思.这个是scanf的一个语法.就是在%和格式字符之间加一个*号就可以跳过这个输入数字.比如当执行语句:scanf("%c,%*c,%c",&a,&b);时,我输入m,n,p三个字母后,a的值为m,b值为p,n被跳过了。


个人认为第三种方法最为简便而且有效哦!O(∩_∩)O








1 0
原创粉丝点击