发生错误时Scanf返回1而不是0

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

我已经阅读到scanf的返回值指示它是否能够成功读取和转换值。我已经使用返回值来检测输入是否为整数,但是输入是否为4.5 scanf返回1,如果输入为g scanf返回0。她是我的代码:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int x;
    int ReturnedValue=scanf("%d",&x);
    printf("Scanf Returned:%d",ReturnedValue);
    return 0;
}

在多篇不同的文章中,您建议使用返回的scanf值检测整数,但为什么现在不起作用?

c input return scanf c99
5个回答
5
投票

返回值不表示成功或失败。它是成功转换的值的数量。

这就是为什么在[4.5]上以"%d"作为格式得到“ 1”,而将“ 4”转换为的原因。

您将通过阅读scanf()的文档来找到它。


3
投票

问题是scanf(或atoi)在解析整数方面并不可靠。

在您的情况下,scanf找到4并对此感到满意,这说明了返回码1。

最安全的方法是使用strtolstrtoul ..原语,以确保word作为整数有效(有关更多详细信息,请检查How to scanf only integer?,答案为“不要”)。使用scanf“ BTW:))

在您的特定情况下(卡在scanf上),您could首先通过按float进行扫描(在float变量上使用%f)可以使输入更加健壮。并检查浮点值是否为integer

float xf;
if (scanf("%f",&xf) == 1)
{
     // one integer or float was scanned
     x = (int)xf;
     if (x==xf)
     {
        // scanned value is an integer: valid
     }
}

但是像4XXXX这样的输入仍将被错误地接受。如果您have使用scanf,则必须承担一定程度的风险。


0
投票

我已经使用返回值来检测输入是否为整数,但是如果输入为4.5,则scanf返回1,如果输入为g,则scanf返回0。

在这种情况下,这实际上是有道理的。

int ReturnedValue = scanf(“%d”,&x);

记住scanf返回值是正确解析的项目数。

  • 如果输入4.5,它将仅读取第一个数字4并正确解释int值。它将丢弃输入中所有剩余的无效字符。

  • 如果输入d,则scanf完全失败(它无法解析任何int),因此它返回0。

请参阅scanf手册-了解为什么将4.5解析为整数4:

[当最大已到达或找到不匹配的字符首先发生。

http://man7.org/linux/man-pages/man3/scanf.3.html


0
投票

我起初不想写一个答案,而在后面留下评论。我想要扩展Jean-François Fabre的答案。

scanf家庭的问题是他们没有做大多数人做的事相信他们这样做,然后就为何这样做“奇怪”感到困惑。实际上,他们根据格式扫描输入并为变量(通过指针传递)。当他们遇到错误时,即某事与格式不匹配,则它们停止。

[格式为"%d",您只是说读整数。格式不说“读一个整数,只有一个整数”。为此,您还需要排除其他所有内容,如果我没有记错的话,那将是此"%d[^0-9]*"(我还没有测试它是否正确)。这就是为什么用户输入4.5scanf。请注意,scanf的操作不正确,您正在指定它错误地,因为您假设"%d"的意思是“以及整数和整数仅”。

您可以看到,很难找到一种可以一切,还告诉您用户何时出错。用户输入又名什么用户输入的内容是随机的,可能包含(无意间)错误,请格式等。因此,您最终会得到非常复杂的格式,只能确定用户在末尾添加了一个点,如果这样做则失败。

这就是为什么我的建议是通过fgets读取while输入,然后使用更好的东西分析格式为strtol或什至sscanf的输入,如果格式正确的话。

这里是strtol的用法示例:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    const char *entries[] = { "4.5", "4", "some random text" };
    char *ptr;

    int i;
    for(i = 0; i < sizeof entries / sizeof *entries; ++i)
    {
        long int res = strtol(entries[i], &ptr, 0);

        if(*ptr != '\0') {
            printf("The input '%s' is not an integer. The non-integer is '%s'\n", entries[i], ptr);
        } else {
            printf("The input '%s' is an integer: %ld\n", entries[i], res);
        }
    }

    return 0;
}

返回]

The input '4.5' is not an integer. The non-integer is '.5'
The input '4' is an integer: 4
The input 'some random text' is not an integer. The non-integer is 'some random text'

这是检查整个输入是否为整数的更精确的方法。


0
投票

我被迫在拼贴中使用scanf

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