C语,scanf出错了,不知道怎么回事

main.c
d:\my documents\visual studio 2010\projects\vs开发\vs开发\main.c(58): warning 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.
e:\program files\microsoft visual studio 10.0\vc\include\stdio.h(304) : 参见“scanf”的声明
d:\my documents\visual studio 2010\projects\vs开发\vs开发\main.c(97): error C2055: 应输入形参表,而不是类型表
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
scanf("%d",q);
h9fz(x,q);//这个是函数调用,q在函数的作用是做为数组的行。这个函数是给结构体里的数组赋值。不知道哪出问题了,VS提示到这个函数出问题;
#endif
_CRTIMP void __cdecl rewind(_Inout_ FILE * _File);
_Check_return_opt_ _CRTIMP int __cdecl _rmtmp(void);
_Check_return_ _CRT_INSECURE_DEPRECATE(scanf_s) _CRTIMP int __cdecl scanf(_In_z_ _Scanf_format_string_ const char * _Format, ...);
_Check_return_opt_ _CRT_INSECURE_DEPRECATE(_scanf_s_l) _CRTIMP int __cdecl _scanf_l(_In_z_ _Scanf_format_string_ const char * _Format, _In_opt_ _locale_t _Locale, ...);
这是编绎过的。不知道贴出来有没有用,

#pragma warning(push)

转载自:

网页链接

VS中”This function or variable may be unsafe.”警告的解决办法

问题原因

C语言的标准函数中,一些读取或写入内存的函数存在内存越界的问题,从而使得内存数据变得不安全。如scanf、gets、strcat等函数都存在着这样的问题。

为了避免这个问题,在VS中,另外提供了如scanf_s,get_s,strcat_s等相关的改进函数,来替代原来的标准函数的功能,并通过添加内存读取范围的限制来解决不安全的问题。

在实际的应用中,也许使用VS提供的安全函数会更加合理。但是,在学习中,几乎所有的课本以及教程都使用的原来的标准函数,另外考虑到移植性的问题,除了VS环境,其他环境中并没有提供改进后的函数。因此,我们通常任然需要标准的库函数来实现相关功能。

但是,如果在VS中使用原始的函数,编译器将会报错。这对使用和学习都带来了相当的不变。


问题分析

在VS2013中,以scanf为例。

如果在程序中使用了scanf函数,如下


#include <stdio.h>

int main()

{

    char c[20];

    scanf("%s", c);

    puts(c);

    return 0;

}

1

2

3

4

5

6

7

8

编译将得到如下错误信息。


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_s代替该函数。

如果要取消禁用,请定义_CRT_SECURE_NO_WARNINGS。

更多信息请查看在线帮助


scanf的声明如下


_Check_return_ _CRT_INSECURE_DEPRECATE(scanf_s) _CRTIMP int __cdecl scanf(_In_z_ _Scanf_format_string_ const char * _Format, ...);

1

在scanf的声明中,在函数的标准形式说明之前,还用到了几个宏定义,正是因为这几个宏定义才实现了scanf函数的禁用。

在VS中利用F12可以看到这几个宏的定义,宏定义具体内容如下


sal.h

#define _Check_return_           _SAL2_Source_(_Check_return_, (), _Check_return_impl_)


crtdefs.h  

#define _CRT_INSECURE_DEPRECATE(_Replacement) _CRT_DEPRECATE_TEXT("This function or variable may be unsafe. Consider using " #_Replacement " instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.")


crtdefs.h 

#define _CRTIMP __declspec(dllimport)

1

2

3

4

5

6

7

8

上面三个宏都包含了宏的嵌套调用,相关宏略多,因此在此不对其进行深入研究。

不过在第二个宏定义中,我们可以很容易发现在编译时,编译器向我们返回的错误信息。这进一步说明了scanf函数不能使用与这几个宏有关。


问题解决

在编译器给出的错误提示中,实际上已经为我们给出了一个明确的解决方案。我们只需要在程序的开头添加一个宏定义便能够解决问题。


#define _CRT_SECURE_NO_WARNINGS

1

加入宏定义后,源代码变为如下形式


#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

int main()

{

    char c[20];

    scanf("%s", c);

    puts(c);

    return 0;

}

1

2

3

4

5

6

7

8

9

再次进行编译,编译成功完成。


虽然按照上述的方法能够顺利解决问题,但是在实际的应用中,如果我们要求只能够使用标准库中的函数,而不能使用VS为我们提供的改进函数。那么我们每次在使用到相关函数时,都需要在文件前面,或者在头文件中添加相关宏。这样未免太麻烦。

既然我们不需要VS给我们提供的这个多余的改变,那有没有一个一劳永逸的办法解决这个问题呢。

方法是有的,这需要我们对VS的项目属性进行设置,具体步骤如下。


在项目属性设置中找到选项卡配置属性→C/C++→预处理器;

在右侧的参数中找到预处理器定义,编辑其参数;

在参数的末尾添加定义_CRT_SECURE_NO_WARNINGS

这样,在编译器进行预处理时,预处理器就会自动在程序开头添加我们需要的宏定义,而不再需要我们手动添加。

在文件中不添加宏定义的情况下,再次进行编译。发现编译顺利完成。

这种方案因为修改的是项目的配置参数,因此适用于整个项目。在该项目中,将不再需要添加相关宏定义。但是其他项目自然不受该设置的影响,因此,如有需要,在其他项目中需要再次进行相同配置才能生效。

————————————————

版权声明:本文为CSDN博主「夏苍」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/u012534008/java/article/details/54602774

温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-04-22
应该是scanf("%d",&q);
提示是说scanf可能不安全,主要是因为scanf使用了指针,可以使用流代替追问

q不是指针。流是数组吗

本回答被提问者采纳
第2个回答  2020-04-26
Visual2019的变成scanf_s
第3个回答  2011-04-22
应当是scanf("%d",&q[i]);i是位置
相似回答