【问题标题】:Scanf %i with letters gives negative number?带有字母的Scanf %i 给出负数?
【发布时间】:2021-04-08 04:10:45
【问题描述】:

我基本上通过解决问题解决了我的问题,但我只是想了解为什么会发生这种行为,所以首先我的代码:

#include <stdio.h>
#pragma warning(disable : 4996) // Just so MVS stops having a meltdown over scanf.

/* Simple question and answer of math equasion. */

int main() 
{
    printf("What is 5 + 5?\n\nAnswer: ");

    int userInput;
    if (scanf("%i", &userInput) && userInput != (5 + 5)) // Give 'userInput' a variable from scanf and compare to hard coded answer.
    {
        printf("\nIncorrect!\n");
        return 0;
    }

    printf("\nCorrect!\n"); // Else without the 'else'.
    return 1;
}

这很简单,是硬编码的数学问题,需要用户回答。对于匹配userInput 的答案,预期响应是正确的,任何不匹配的都被认为是不正确的。当我传递一堆字母或只是简单地传递“asdf”时,它会将其视为正确并吐出一个负数:-858993460。

我的解决方法是将|| userInput &lt; 0 添加到我的 if 语句中,如下所示:

if (scanf("%i", &amp;userInput) &amp;&amp; userInput != (5 + 5) || userInput &lt; 0)

所以基本上这个问题已经用一些 flextape 处理了,但我似乎无法回答的问题是:“为什么不管我输入什么字母或非数字字符,它都会吐出负数?”

如果这个问题已经得到解答,我深表歉意。我尝试使用我能想到的任何关键字进行搜索。

【问题讨论】:

  • “吐出负数”是什么意思?显示的代码中没有任何内容可以打印数字。无论如何,核心问题是代码并不完全正确。如果输入了无效输入,scanf 将返回 EOF。在这种情况下,您的原始代码仍将其视为正确的情况。检查应该是scanf() == 1
  • 如果我在输入字母时在正确的下方添加printf("i%", userInput);,这就是它给我所说的负数的地方。抱歉,我应该将其添加到代码中。
  • 那是因为scanf 失败并且没有为userInput 设置任何值。由于userInput 没有初始化,在这种情况下它只会包含垃圾数据。除非scanf 成功,否则不得使用userInput
  • 不,如果scanf 失败,它根本不会触及userInput。这只是变量中碰巧出现的任何随机垃圾。访问未初始化的变量是未定义的行为,因此该值是不可预测的并且没有意义。
  • 另外,您几乎肯定不想将scanf%i 一起使用,或许应该使用%d%i 将接受八进制数字,因此如果您输入 012,那也是正确的,因为 012 Dec 是 010 Dec.

标签: c string math integer scanf


【解决方案1】:

scanf 函数返回匹配项的数量,因此在布尔值内容中,如果您输入了一个数字,它的计算结果为 true,如果您没有输入,则返回 false。这也意味着没有值被写入userInput,所以它的值(因为它没有被初始化)仍然是indeterminate

这意味着如果用户输入了数字并且不是 10,则您的条件表明答案为“不正确”,因此如果您没有输入数字,则认为答案是正确的。如果不是输入了一个数字输入的数字不是 10,则您希望打印“不正确”:

if (!scanf("%i", &userInput) || userInput != (5 + 5)) 

【讨论】:

  • 有趣。感谢您的回答。我仍然习惯于逻辑约定。我对额外指令的初步想法让我认为现在使用我的代码 sn-p 的更好路线是交换条件。我应该选择为正确的答案做一个 if 语句,而不是为某个错误做一个 if 语句,如果它与 (5 + 5) 不匹配,那么它会将它传递到另一部分。不过据我现在了解,userInput 只会产生随机的垃圾数据,所以在打印时,如果遇到字母,它会给我说的输出?
  • @BluZero 你想先检查scanf 是否成功(这段代码就是这样做的),如果成功则只读取userInput
  • 如果在第一次有效转换或匹配失败之前达到输入结尾,则返回EOF(通常为-1),这也将使用scanf("%i", &amp;userInput)测试为true
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-05
  • 2013-05-04
  • 2015-08-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多