首页 > 解决方案 > 为什么 scanf() 没有变成两个浮点数

问题描述

我是 C++ 的新手,我遇到了一些问题。要解决的问题是有 5 个输入,输入可以包括整数和字符串“none”,尝试对输入中的整数求和,结果应该是双精度数。这是我所做的:我在数组中放入了五个输入并使用 scanf() 将它们变成双精度,但是当我输入 none 并使用 printf 查看数组时,我发现它变成了两个浮点数,scanf将字符串转换为双精度有任何限制吗?

这是代码:

int main()
{
    double sc[5];

    for (int i = 0; i < 5; i++) {
        sc[i] = 3;
        scanf("%lf", &sc[i]);
        printf("%lf\n", sc[i]);
    }
}

输出是:

34
34.000000
none
3.000000
3.000000
56
56.000000
89
89.000000

标签: c++doublescanf

解决方案


当且仅当输入是有效的浮点数时,调用scanf("%lf", &something)才会填充。something该字符串none不是一个有效的数字

你得到两个3值的原因可能是因为nan 它是一个有效的浮点数,所以scanf找到n并说“哈,这将是一个nan”。但随后它发现,令其失望的是,o并决定它不再有效。

但它已经no从输入流中读取了。然后它返回并与ne (a)做同样的事情。

在那之后,你开始再次给它有效的数字,让它继续。


如果您希望能够处理字符串数字,您将不得不使用限制最少的(字符串)然后再决定。像这样的东西(虽然scanf("%s")对真正的代码很危险,但对课堂作业来说可能没问题):

以下代码执行此操作并(如您应该)检查返回值scanf/sscanf以确保它被正确扫描:

#include <stdio.h>
#include <string.h>

int main() {
    static char bigstring[1000];
    double sc[5];

    for (int i = 0; i < 5; i++) {
        sc[i] = 3;
        if (scanf("%s", bigstring) != 1) {
            puts("*** Could not get input");
            return 1;
        }

        if (strcmp("none", bigstring) == 0) {
            puts("Got 'none', converting to -999");
            sc[i] = -999;
        } else if (sscanf(bigstring, "%lf", &sc[i]) != 1) {
            printf("*** Could not convert input '%s' to float", bigstring);
            return 1;
        } else {
            printf("Got %f\n", sc[i]);
        }
    }

    puts("\nThe five entered numbers were:");
    for (int i = 0; i < 5; i++) {
        printf("   %lf\n", sc[i]);
    }
}

使用基本测试数据正常运行:

pax:~$ printf "34\nnone\n56\n89\n111\n" | ./qq
Got 34.000000
Got 'none', converting to -999
Got 56.000000
Got 89.000000
Got 111.000000

The five entered numbers were:
   34.000000
   -999.000000
   56.000000
   89.000000
   111.000000

(a)有趣的是,这似乎只发生在真实的用户输入中,而不是按照我的printf陈述通过程序传输数据。

在我看来,理想的行为是让输入流指向无效数据。换句话说,除非确切的文本是有效的(如nan),否则指针根本不应该移动。但是,C 标准中有一个脚注允许这种行为,例如,如果输入流不可搜索:

fscanf将最多一个输入字符推回输入流。

因此,虽然它可能能够比管道上的备份更远,但在处理终端输入时可能并非如此。

当我x作为输入输入时,它似乎确实将其推回,因为后面的每个数组元素都填充了3,这意味着它正在x连续读取它。任何以 an 开头的东西n似乎只消耗那个和下面的字符。


推荐阅读