在格式控制字符串中使用消息

Using messages inside format control string

在使用scanf函数时,我一直在使用像scanf("%d",&x);这样的格式字符串。不过前几天有点好奇,所以想问一下。

将字符放在 scanf 函数的引号中会发生什么?

示例:

printf("Please enter the date you were born: ex.1999/5/6 : ")
scanf("%d/%d/%d", &year, &month, &date);

What happens when you put a character in the quotation marks of the scanf function?

它会导致函数从输入流中跳过一次出现那个确切字符,前提是下一个要读取的字符是一场比赛。如果下一个字符 不是 匹配项,那么此时对 scanf 的调用将失败。

来自 cppreference:

The format string consists of

  • non-whitespace multibyte characters except %: each such character in the format string consumes exactly one identical character from the input stream, or causes the function to fail if the next character on the stream does not compare equal.

因此,请考虑以下几点:

int i, j;
int count = scanf("%dbob%d", &i, &j);

对于 1bob2 的输入,这将成功地将 12 的值分别读入 ij(跳过3 bob 个字符),返回的 count 值将是 2.

然而,对于 1Bob2 的输入,1 将被读入 i 然后调用将失败,因为下一个字符 (B) 不是b,返回的count值只会是11bOb21boB2.

也会发生同样的情况

scanfstdin 读取数据流并尝试解析您的格式字符串。如果不合适,它会停止处理。重要的是要了解输入的其余部分保留在 stdin 流中以供后续读取。 scanf returns 已成功解析的值数。

根据我的经验,最好自己编写一个小程序并测试其行为:

#include "stdio.h"

void main() {
        int year = 0;
        int month = 0;
        int date = 0;
        int count;

        while (1) {
                printf("enter data:\n");
                count = scanf("%d/%d/%d", &year, &month, &date);
                printf("data received:\n");
                printf("%d-%d-%d count=%d\n", year, month, date, count);
        }
}

示例 1:重新开始并输入正确的数据:

enter data:
1/2/3
data received:
1-2-3 count=3

示例 2:重新启动并输入错误数据:

enter data:
1 2 3
data received:
1-0-0 count=1
enter data:
data received:
2-0-0 count=1
enter data:
data received:
3-0-0 count=1

可以看到scanf只读取了1之后的space的数据,因为它不适合格式字符串。 scanf 只改变第一个变量的值。您输入的其余部分 2 3 仍在 stdin 中。循环继续,下一次调用 scanf 读取 2。跳过数字前面的space。这发生在没有任何用户交互的情况下!再次没有找到斜线。等等。在不同的情况下亲自尝试并了解使用 scanf 是一件危险的事情......如果您不初始化变量并且解析失败,您将获得未初始化的数据!