gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 05:32:16 26 4
gpt4 key购买 nike

这是我的 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 时,输出为 You wrote: minx is 5 x is 3 这是有道理的.但是,当输入为 5 -35 - 36 -4 时,输出为 You wrote: minx is 5 x 为 8。我希望 - 跳过空格,所以我希望 minx5x 364 用于其他输入。当 %d-%d 中的 - 更改为 ?*+< 时也会发生这种情况 即使输入相同。我知道这可能是因为第一个 int 之后的那个空间。这里说只有三个格式说明符不跳过空格 — Whitespace before %c specification in the format specifier of scanf function in C .我弄错了吗?为什么 - 不跳过这里的前导空格?这里的实际问题是什么,它的原因是什么?为什么是8?还有哪些运算符或字符会导致类似问题?

最佳答案

让我们详细看看您的scanf 格式说明符"%d-%d":

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

所以输入 5-35-3 都工作得很好。但是当输入是 5 -3(或者任何在 - 之前有空格的东西)解析失败,因为 scanf 没有立即看到它期望的 -

如果这不是您所期望的,或者不是您想要的,或者如果那没有意义,或者如果这不是您希望 scanf 工作的方式,恐怕那是太糟糕了:scanf 按照它的方式工作。

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

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

我对您的建议取决于该计划的最终目的。

  • 如果它只是为了学习,那么请尽量减少花在关注程序输入方式上的时间。例如,如果您需要读取一个整数,请使用一个 %d。只要你能得到你需要的数字到你的程序中(这样你就可以测试你程序的其余部分),你就没事了。如果您可以键入某些内容导致 scanf 感到困惑,请不要担心,不要键入这些内容即可。不要尝试做任何花哨的事情——这不是scanf的目的。
  • 如果这是一个“真正的”程序,它确实必须接受任意用户输入,或具有特定语法的输入(例如在正确位置使用 -),并且如果您需要优雅地处理不正确的输入,打印适当的错误,而不是读取错误的值或感到困惑 — 然后 run, do not walk, away from scanf ,并且永远不要再使用它。使用 scanf 编写执行高质量输入的程序实际上是不可能的。即使是 C 专家也做不到。这根本不值得。与您简单地放弃 scanf 并使用 fgets 或类似方法一次读取您的输入相比,您将花费五倍的时间并得到较差的结果,然后解析了输入行(甚至可能使用 sscanf — 但再次检查其返回值)。

附录:确实如此,所有格式说明符 — 除了三个异常(exception)(%c%[…] 扫描集和 %n ) — 在开始他们的工作之前跳过空格。但是格式说明符是以 % 开头的。格式字符串中的文字字符必须完全匹配,并且没有隐式跳过它们的空格。如果您想跳过输入中除执行此操作的 % 格式说明符之前的位置处的空白,您可以在格式字符串中包含文字空白字符(通常是单个空格)。

关于c - 使用 scanf() 获取的整数在 C 中未获得其预期值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58401959/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com