错误C4996: 'scanf': 在C编程中,此函数或变量可能存在安全隐患。

28

我创建了一个小应用程序,使用带参数的用户定义函数来查找最大数。当我运行它时,它显示以下消息:

Error 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.

我该怎么解决这个问题?

这是我的代码:

#include<stdio.h>

void findtwonumber(void);
void findthreenumber(void);

int main() {
    int n;
    printf("Fine Maximum of two number\n");
    printf("Fine Maximum of three number\n");

    printf("Choose one:");
    scanf("%d", &n);
    if (n == 1)
    {
        findtwonumber();
    }
    else if (n == 2)
    {
        findthreenumber();
    }
    return 0;
}

void findtwonumber(void)
{
    int a, b, max;
    printf("Enter a:");
    scanf("%d", &a);
    printf("Enter b:");
    scanf("%d", &b);
    if (a>b)
        max = a;
    else
        max = b;
    printf("The max is=%d", max);
}

void findthreenumber(void)
{
    int a, b, c, max;
    printf("Enter a:");
    scanf("%d", &a);
    printf("Enter b:");
    scanf("%d", &b);
    printf("Enter c:");
    scanf("%d", &c);
    if (a>b)
        max = a;
    else if (b>c)
        max = b;
    else if (c>a)
        max = c;
    printf("The max is=%d", max);
}

5
这是一个被视为错误的警告。要么按建议去做,用 scanf_s 替换 scanf,要么将其禁用,因为它在告诉你什么。 - Eugene Sh.
只是一个编译器警告。scanf_s可以防止可能的缓冲区溢出。请参见http://code.wikia.com/wiki/Scanf_s。 - user3742467
2
我不确定问题是什么。要么替换,要么禁用: #define _CRT_SECURE_NO_WARNINGS - Jiminion
可能是为什么Visual Studio 2013会在C4996上出错?的重复问题。 - MicroVirus
7个回答

20

听起来这只是一个编译器警告。

使用scanf_s可以防止可能发生的缓冲区溢出。
参见:http://code.wikia.com/wiki/Scanf_s

很好地解释了为什么scanf可能危险:Disadvantages of scanf

因此,建议您尝试将scanf替换为scanf_s或禁用编译器警告。


12
如何禁用编译器警告? - VOLVO
14
@VOLVO: 为了禁用编译器警告,请在程序的最顶部添加以下语句:#define _CRT_SECURE_NO_WARNINGS - AboAmmar
1
维基百科链接中提到 scanf_s 是“与 scanf 相同,只是更安全。” 那么,如果一个实现可以支持 scanf_s,是否有任何理由让 scanf 不链接到相同的函数? - supercat
1
@supercat: 很多,包括效率和可移植性。 - DevSolar
1
@supercat:如果你只是匆匆浏览论文,试图找到一个好的反对方式,那么“论文中没有提到”这个说法是不正确的。事实上,该论文的每个部分都至少包含一个可应用于scanf_s的项目。最重要的是,在我看来,关于可用实现的部分。如果你比论文中提到的更了解相关论点,为什么还要询问它们呢? - DevSolar
显示剩余3条评论

17

抑制错误的另一种方法:在C/C++文件顶部添加以下行:

#define _CRT_SECURE_NO_WARNINGS

13
需要澄清的是,“at the top” 意味着“在 #include 行之前”。举个例子,如果你将其放在 #include<stdio.h> 之后,仍然会收到警告,因为当你禁用它时已经太晚了。请注意保持原始意思,使语言更加通俗易懂。 - Fabio says Reinstate Monica
2
@FabioTurati提到了一个非常重要的观点。每当我们创建一个默认的CPP项目时,它会创建一个包含“main”方法的<projectName>.cpp文件。为了引用所有头文件,它会引用一个名为stdafx.h的集中式头文件,其中包含所有的包含语句。因此,当我在所有包含语句之前在<projectName>.cpp文件的顶部写入#define _CRT_SECURE_NO_WARNINGS时,它并没有起到作用。但是,当我将其添加到stdafx.h文件的顶部时,最终错误消失了。 - RBT
2
或者,将 /D_CRT_SECURE_NO_WARNINGS /wd4996 添加到您的编译选项中。 - DevSolar

16

您可以在预处理器定义中添加“_CRT_SECURE_NO_WARNINGS”。

右键单击您的项目->属性->配置属性->C/C++->预处理器->预处理器定义。

enter image description here


1
当您创建一个新项目时,另一种方法是不点击安全开发生命周期(SDL)检查:
或者,如果您已经在项目中: 右键单击您的项目->属性->配置属性->C/C++ ->所有选项>滚动鼠标并找到SDL检查,您将其编辑为NO(/sdl-),然后应用,确认。

0

#define scanf scan_f

用安全版本替换不安全版本。


0

为了禁止编译器警告,请在程序的顶部添加以下语句:#define _CRT_SECURE_NO_WARNINGS


0
简单的答案是: scanf() 函数读取从第一个字符到第一个空格之间的字符/字符串。

1
这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - freestyle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接