为什么当我输入“1 1.5”时,scanf("%d %d")会忽略“.5”?

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

为什么当我运行这段代码时:

#include <stdio.h>

int main () {
    int a, b;
    if (scanf("%d %d", &a, &b) == 2)
        printf("%d %d", a, b);
    else 
        printf("Something went wrong");
    return 0;
}

并输入例如:

1 1.5

输出为:

1 1

为什么 scanf 会读取“.”之前的两个数字并忽略“.5”?如何检查最后一个数字不是浮点数并且字符串结束?

操作系统:MacOS/linux 编译器:gcc

我只想运行上面的代码

输入:

1 1.5234

(一些浮点数)

输出:

Something went wrong
c scanf
2个回答
1
投票

fgets:读取整行输入,确保捕获用户输入的所有内容,直到他们按 Enter。这避免了 scanf 在第一个不匹配字符处停止的限制。

sscanf:解析input中存储的输入。它尝试读取两个整数 (%d %d)。之后,它尝试再读取一个字符 (%c),该字符应该是空格(如空格或换行符)。

验证:

if (sscanf(input, "%d %d %c", &a, &b, &leftover) == 2)

检查是否成功读取了两个整数。
isspace(leftover)
:检查第二个整数后面的字符是否为空格(确保没有小数点等其他字符)。

输出:如果输入格式匹配(scanf 成功读取两个整数后跟空格),则打印整数。否则,它会打印一条错误消息。


0
投票

又一个scanf问题!我的幸运周。 :-)

简短的回答是,你无法真正弄清楚 scanf 发生了什么。它的手册页毫无帮助地指出:

正确使用这些函数非常困难,最好使用 fgets(3) 或 getline(3) 读取整行,然后使用 sscanf(3) 或更专业的函数(例如 strtol(3))解析它们。

scanf(和fscanf)很容易与输入不同步。我使用 fgets 和 sscanf。有了这些,我可以大大改进您的输入验证,如下所示:

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

int main () {
    char iline[80];
    int a, b;
    char extra[2];
    int result;

    if (fgets(iline, sizeof(iline), stdin) == NULL) {
        printf("Need an input line.\n"); exit(1);
    }

    result = sscanf(iline, "%d %d%1s", &a, &b, extra);
    if (result == 2) {
        printf("%d %d\n", a, b);  // Success!
    } else  if (result == 3) {
        printf("Extra stuff starting at '%s'\n", extra);
    } else if (result < 2) {
        printf("Could not find two integers\n");
    }
    return 0;
}

以下是一些测试运行:

$ gcc x.c
$ echo "1" | ./a.out
Could not find two integers
$ echo "1 2" | ./a.out
1 2
$ echo "1 2.5" | ./a.out
Extra stuff starting at '.'
$ echo "1.5 2" | ./a.out
Could not find two integers
$ echo "1 2 5" | ./a.out
Extra stuff starting at '5'

通过与扫描分开读取该行,您可以添加“额外”字符串来测试扫描是否在该行被消耗之前提前结束。如果我在上面的代码中使用 scanf,它将拒绝返回,直到它真正找到需要扫描的额外内容。

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