第一个格式字符串字符不是空格时 scanf 的行为

Ami*_*ram 1 c scanf format-string

scanf应该消耗并丢弃格式字符串中不属于转换说明符的任何字符。但当非空白非转换字符出现在格式字符串的前面时,其行为似乎有所不同。为什么?

int main() {
    int num, num2;
    printf("> ");
    while (scanf("> %d %d", &num, &num2)) {
        printf("You entered the number %d %d.\n", num, num2);
        printf("> ");
    }
    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

如果您构建并运行它并输入

int main() {
    int num, num2;
    printf("> ");
    while (scanf("> %d %d", &num, &num2)) {
        printf("You entered the number %d %d.\n", num, num2);
        printf("> ");
    }
    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

在提示符处,它打印消息和重复的提示符,然后立即退出。

因此,这意味着第一次scanf返回,然后在用户可以输入另一组令牌之前返回。如果您从格式字符串中删除,则循环将运行,直到用户输入非数字的内容,然后导致返回- 这是我期望的行为。20> scanf0

另外,如果我在第一个转换说明符之后放置相同的符号,则循环将继续按预期运行。也就是说,如果格式字符串具有,例如,"%d > %d"并且用户输入

> 3 4
Run Code Online (Sandbox Code Playgroud)

循环将再次运行并接受另一轮输入。

我还没有看到任何有关此行为的文档。

Oka*_*Oka 5

来自一些文档fscanf

格式字符串由以下部分组成

  • 非空白多字节字符,除了%:格式字符串中的每个此类字符都会消耗输入流中的一个完全相同的字符,或者如果流中的下一个字符不相等,则导致函数失败。

虽然fscanf说明符%d消耗所有1 个 前导空格,但它不消耗其后面的换行符,并且在后续迭代中'>'完全匹配换行符 ( '\n')。

来自同一文档:

  • 空白字符:格式字符串中的任何单个空白字符都会消耗输入中所有可用的连续空白字符(就像通过在循环中调用isspace来确定一样)。请注意,格式字符串中的"\n"" "、或其他空格之间没有区别。"\t\t"

因此,格式说明符中的前导空格将消耗输入中的尾随换行符:

#include <stdio.h>

int main(void)
{
    int num, num2;

    while (1) {
        printf("Enter \"> NUM NUM2\": ");

        if (2 != scanf(" > %d %d", &num, &num2))
            break;

        printf("You entered the number %d %d.\n", num, num2);
    }
}
Run Code Online (Sandbox Code Playgroud)
#include <stdio.h>

int main(void)
{
    int num, num2;

    while (1) {
        printf("Enter \"> NUM NUM2\": ");

        if (2 != scanf(" > %d %d", &num, &num2))
            break;

        printf("You entered the number %d %d.\n", num, num2);
    }
}
Run Code Online (Sandbox Code Playgroud)

旁白:这将在真实的返回值上永远循环EOF(负数int,几乎普遍存在-1):

while (scanf("> %d %d", &num, &num2))
Run Code Online (Sandbox Code Playgroud)

您应该显式检查 的返回值是否scanf预期的转换说明符数量(即2)。


1.与除 %c%[和之外的所有格式说明符一样%n(假设没有发生错误)。