几天前,我才刚开始学习C编程,我正在从Kattis(open.kattis.com)网站上尝试一些问题。在我不太了解这意味着什么的过程中,我想到了这个问题。
//two stones
#include <stdio.h>
int main()
{
int n,x=2;
printf("The number of stones placed on the ground is ");
scanf("%d",&n);
if (n%x != 0)
{
printf("The winner of the game is Alice! \n");
}
else
{
printf("The winner of the game is Bob! \n");
}
return 0;
}
出现了>>
警告:忽略使用属性warn_unused_result声明的scanf返回值[-Wunused-result] 关于scanf(“%d”,&n);
任何人都可以解释这是什么问题以及如何纠正此问题?谢谢。
答案 0 :(得分:3)
scanf
的返回值指示成功:
C标准; §7.19.6.4.3:
如果在输入失败之前发生输入失败,scanf函数将返回宏EOF的值 任何转换。否则,scanf函数返回输入项的数量 分配的数量,该数量可能少于所提供的数量,如果为早,则为零 匹配失败。
如果在调用scanf
的过程中有一个带有格式说明符的格式字符串,则可以检查scanf
是否已成功从stdin
接收到该类型的输入将其返回值与1进行比较。
您的编译器警告您这一点不是特别因为scanf
返回一个值,而是因为检查scanf
的结果很重要。例如,printf
的符合标准的实现也将返回一个值(第7.19.6.3.3节),但这对于检查程序的健全性并不关键。
答案 1 :(得分:2)
您将忽略scanf调用的返回值。
这就是编译器警告的内容,并被告知将其视为错误。
请理解,用scanf()可能会犯很多细微的错误,而不在乎成功,这由返回值表示。
要隐藏编译器会通知您的问题,我建议您首先尝试“显而易见”的直接方法
int IreallyWantToIgnoreTheImportantInfo;
/* ... */
IreallyWantToIgnoreTheImportantInfo = scanf("%d",&n);
但是,这只会将问题转移到其他地方,而忽略scanf()返回值的有效原因很可能(或可能是“希望”)变成“变量集,但从未使用过”警告。
在这里真正解决问题的正确方法是使用返回值。 您可以例如进行循环,尝试读取用户输入(给出解释并删除未扫描的尝试),直到返回值指示成功。
这可能会使代码更好,至少更健壮。
如果您真的想忽略而不是忽略包含信息的变量,请尝试
(void) scanf("%d",&n); /* I really really do not care ... */
但是,请按照我的意思认为这完全有用,这不是一个好主意。
答案 2 :(得分:1)
有人可以向我解释这是什么问题以及如何纠正此问题吗?
许多C函数将值返回给它们的调用者。 C不需要调用者确认或处理此类返回值,但是通常,忽略返回值会构成程序缺陷。这是因为忽略返回值通常意味着以下情况之一:
调用该函数是为了获取其返回值,因此对该值执行任何操作本身就是错误,或者
该函数主要是由于其副作用而被调用的,但是它的返回值(传达了有关函数成功产生这些副作用的信息)被忽略了。有时,调用者确实并不在乎函数的成功程度,但是通常,忽略返回值意味着程序正在假定完全成功,因此,如果未真正实现,则它将出现故障。
scanf()
的副作用是:从标准输入中读取格式化的数据并将其记录在指定的对象中。它的返回值指示成功处理了多少个给定的输入字段,并且如果在解析任何字段之前遇到流的末尾或I / O错误,则返回值也将通过特殊的返回值来指示。
如果您不验证scanf
是否阅读了您希望它执行的所有字段,那么您将不知道它是否为您提供了任何可使用的数据,也无法确定输入的状态。例如,假设您在运行程序时输入“ x”而不是数字。您认为它将做什么?
您似乎正在使用GCC和GLIBC。当忽略某些函数(包括scanf
)的返回值时,默认情况下会使用它们来产生警告。这捕获了许多更常见的此类漏洞案例。为避免此类警告,请正确检查返回值。例如,
if (scanf("%d",&n) != 1) {
fputs("Invalid input -- aborting.\n", stderr);
exit(1);
}
答案 3 :(得分:0)
发生的情况是,如果不检查scanf返回的值,则会将编译器配置为向您发出警告。
您可以通过多种方式“修复”此问题:
祝你好运!
答案 4 :(得分:0)
您的编译器警告您的是以下内容:
您正在使用scanf()
读取输入(您无法控制)。您告诉scanf()
您期望一个整数"%d"
,并且scanf()
应该将转换结果放入&n
所提供的变量中。
现在,当您的用户未输入整数而是改为使用"evil message"
时,会发生什么?好吧,scanf()
无法将其转换为整数。因此,您的变量n
将不会初始化。 让程序意识到出了点问题的唯一方法是检查scanf()
返回的内容。如果返回的内容表明1
转换成功,则一切正常。如果返回其他值,则说明您已在程序中输入了一些垃圾。 (通常,如果发生错误,您可能会希望通过描述性的错误消息来纾困,但具体情况取决于上下文)
处理输入错误的失败是最容易利用的安全漏洞,并且编译器的开发人员都知道这一点。因此,他们认为忽略scanf()
的返回值通常是一个非常糟糕的主意,因为这是捕获scanf()
输入错误的唯一方法。他们很方便地告诉您有关此的信息。 尝试遵循他们的建议,并确保您确实处理了可能发生的错误,或证明可以安全地忽略这些错误。