scanf Cppcheck警告

Cppcheck为scanf显示以下警告:

消息:没有字段宽度限制的scanf可能会因巨大的输入数据而崩溃。 要修复此错误消息,请添加字段宽度说明符:%s =>%20s%i =>%3i可能崩溃的示例程序:#include int main(){int a;  scanf(“%i”,&a); 返回0; 使它崩溃:perl -e'print“5”x2100000'|  ./a.out 

我无法崩溃这个程序输入“巨大的输入数据”。 我应该输入什么才能让这次崩溃? 我也不明白这个警告中最后一行的含义:

perl -e …

最后一行是一个示例命令,用于演示示例程序的崩溃。 它实质上导致perl打印2.100.000次“5”,然后将其传递给程序“a.out”的stdin(这意味着编译的示例程序)。

首先, scanf()应仅用于测试,而不是在现实世界的程序中,因为它无法正常处理几个问题(例如,询问“%i”但用户输入“12345abc”(“abc”将保持不变)在stdin中并且可能导致以下输入被填充而没有用户更改它们的机会)。

关于这个问题: scanf()会知道它应该读取一个整数值,但它不知道它可以多长时间。 指针可以指向16位整数,32位整数,或64位整数或更大的东西(它不知道关闭)。 具有可变数量的参数(用...定义)的函数不知道传递的元素的确切数据类型,因此它必须依赖于格式字符串(格式标记的原因不是可选的,就像在C#中那样你只是对它们进行编号,例如"{0} {1} {2}" )。 并且在没有给定长度的情况下,它必须假设一些长度,这也可能是平台相关的(使得该函数更难以使用)。

一般来说,认为它可能是有害的,也是缓冲区溢出攻击的起点。 如果您想保护和优化您的计划,请先将其替换为替代方案。

我尝试对C程序运行perl表达式,它在Linux上崩溃了(分段错误)。

通常不推荐在实际应用中使用’scanf’(或fscanf和sscanf)function,因为它不安全,如果提供了一些不正确的输入数据,它通常是缓冲区溢出的漏洞。 在许多常用的C ++库(QT,Microsoft Visual C ++的运行时库等)中输入数字有更安全的方法。 也许你可以找到“纯”C语言的安全替代品。