用scanf()获取的整数在C中未获得其预期值

问题描述 投票:0回答:2

这是我的C代码:

#include "stdio.h"

int main()
{
  int minx, x;

  printf("Enter two ints: ");
  scanf( "%d-%d", &minx, &x);

   printf("You wrote: minx is %d x is %d", minx, x);
}

当输入是5-35--3时,输出是您写道:minx是5 x是3这很有意义。但是,当输入为5 -35-36 -4时,输出为您写道:minx为5 x为8。我期望-跳过空格,所以我期望minx5x364 作为其他输入。即使使用相同的输入,当-中的%d-%d更改为?*+时,也会发生这种情况。我知道可能是因为第一个int之后的空间。在这里它说只有三个格式说明符不会跳过空格-Whitespace before %c specification in the format specifier of scanf function in C。我搞错了吗?为什么-在这里不跳过前导空格?这里的实际问题是什么,其原因是什么?为什么是8?还有哪些其他运算符或字符会导致类似的问题?

c input output scanf
2个回答
4
投票

让我们详细了解scanf格式说明符"%d-%d"

  • [%d如有必要,请跳过空格,然后读取整数
  • [-匹配文字'-'字符
  • [%d如有必要,请跳过空格,然后读取整数

所以输入5-35- 3都可以正常工作。但是,当输入为5 -3(或其他任何在-之前有空格的内容)时,解析将失败,因为scanf不会立即看到它期望的-

[如果不是您所期望的,或者不是您想要的,或者那没有道理,或者如果那不是您希望scanf起作用的方式,恐怕太糟糕了:scanf以其工作方式运行。

您如何解决此问题?这部分取决于您为什么首先在格式字符串中包含-字符。

  • 您可以使用%d%d%d %d,它们将仅读取两个整数(至少由一个空格字符分隔)。如果第二个整数前面有一个-字符,则该整数将被读取为负数。
  • 您可以使用%d -%d,它将在尝试与-字符匹配之前跳过(任意)空格。
  • 您可以使用两个单独的scanf调用。
  • 如果确实继续使用scanf,则确实需要检查其返回值,以便程序可以检测到预期输入不匹配的情况。
  • 最后,您可以使用scanf以外的其他东西。

我对您的建议取决于该程序的最终目的。

  • [如果仅用于学习,则将程序花费在所有输入上的时间减至最少。例如,如果您需要读取一个整数,请使用一个%d。只要您可以在程序中获取所需的编号(以便可以测试程序的其余部分),就可以了。如果您可以输入某些内容导致scanf感到困惑,那就不用担心,不要输入这些内容。不要尝试anything幻想-这不是scanf的目的。
  • [如果这是一个“真实”程序,则必须接受任意用户输入,或接受具有特定语法的输入(例如在正确的位置带有-的输入),并且如果您需要妥善处理错误的输入,打印适当的错误,而不是读取错误的值或感到困惑-然后运行,不要走开,远离scanf,并且永远不要再使用它。实际上,不可能编写使用scanf执行高质量输入的程序。甚至C专家都无法做到这一点。根本不值得。如果您只是简单地放弃scanf并使用fgets之类的内容一次读取输入,然后解析输入行(甚至使用sscanf,则您将花费​​五倍的时间,并得到较差的结果) ] —但再次检查其返回值)。

附录:的确如此,所有格式说明符-除三个例外(%c%[…]扫描集和%n)外-在开始工作之前都要跳过空格。但是格式说明符是以%开头的。格式字符串中的文字字符必须完全匹配,并且不会隐式地跳过它们。如果要跳过输入中除%格式说明符之前的空白处,可以在格式字符串中包含文字空白字符(通常为单个空格)。


2
投票

您需要检查scanf的返回值。通常,应该对您调用的每个具有返回值的库函数执行此操作。

在您的情况下,scanf将为有效输入返回2(表示已设置两个输出参数)。如果您获得任何其他返回值,则输入与您指定的格式不匹配,并且您应忽略输出参数minxx的内容。

© www.soinside.com 2019 - 2024. All rights reserved.