在scanf()格式字符串中尾随空格的影响是什么?

时间:2013-10-21 15:47:39

标签: c scanf

此代码中scanf("%d")scanf("%d ")之间的区别是什么,其中差异是格式字符串中的尾随空白?

#include <stdio.h>

int main(void)
{
    int i, j;

    printf("enter a value for j ");
    scanf("%d  ",&j);
    printf("j is %d\n", j);
    printf("enter a value for i ");
    scanf("%d", &i);
    printf("i is %d\n", i);
    return 0;
}

当我在格式说明符scanf()之后添加空格时,scanf("%d ", &j);函数如何实际工作?

4 个答案:

答案 0 :(得分:19)

scanf格式的空白字符使其显式读取并忽略尽可能多的空白字符。因此,对于scanf("%d ", ...,在读取数字后,它将继续读取字符,丢弃所有空格,直到它在输入上看到非空白字符。该非空格字符将留作输入函数读取的下一个字符。

使用您的代码:

printf("enter a value for j ");

scanf("%d  ",&j);

printf("j is %d \n", j);

它将打印第一行,然后等待您输入一个数字,然后继续等待数字后的某些内容。因此,如果您只键入 5 Enter ,它将显示为挂起 - 您需要键入另一行,其中包含一些非空白字符才能继续。如果您输入 6 Enter ,那将成为i的值,因此您的屏幕将如下所示:

enter a value for j 5
6
j is 5
enter a value for i i is 6

此外,由于大多数scanf%转换也会跳过前导空格(%c%[%n除外),在%转换之前的空格是无关紧要的("%d"" %d"将采取相同的行动)。所以在大多数情况下,你应该避免scanf转换中的空格,除非你知道你特别需要它们的特殊效果。

答案 1 :(得分:6)

格式字符串中的空白字符(空格,换行符,水平和垂直制表符)与输入中的任意数量的空格字符匹配。
在你的第一个案例中

  scanf("%d  ",&j);

当它遇到空白字符(WSC)' '时,它会吃掉用户输入的所有空格,包括按下 Enter \n,它会期待进入非WSC。在这种情况下,您的程序将按 Ctrl + Z 终止。

答案 2 :(得分:4)

scanf格式的空白字符与isspace所描述的任意数量的空白字符相匹配。因此,如果您有尾部空格,换行符,制表符或任何其他空白字符,那么scanf在返回之前也会使用它。

答案 3 :(得分:1)

差异(虽然很明显)是一种不同的格式字符串。如果输入以下行:

"3  "

scanf()将成功返回。否则,它取决于您提供的输入。 scanf()基本上会跳过空格(制表符,空格,换行符),并在输入流中搜索字母数字值。由于这是尾随空格,当按 ENTER 时,它会在输入结尾处与尾随换行符混为一谈,所以这没有什么后果。

scanf()期望提供的输入与您提供给它的格式字符串完全匹配,但连续的空格字符被压缩为单个空白字符。如果要使用等效的字符串处理sscanf()来解析大量数据,这就变得非常重要。

进一步测试这个的好练习将是:

#include<stdio.h>

int main(void)
{
   int a=0,b=0,c=0;

   printf("Enter values for A, B, C, in the format: \"A B  -  C\"\n");
   scanf("%d %d  -  %d", &a, &b, &c);

   printf("Values: A:%d, B:%d, C:%d\n", a, b, c);
}

然后,在提供正确和错误格式化的安慰输入(即:空格和连字符)之后,检查并查看这些整数的值是什么。这是一些示例运行。第一个使用错误输入,第二个使用正确格式化输入。请注意,在第一种情况下,C甚至没有设置,因为如果输入和格式字符串不匹配,scanf()将提供意外行为。一般情况下,最好使用fgets()之类的东西从用户那里获取一串输入,然后使用各种搜索函数(即:strstr(),strch(),strcat,strcpy等)进行解析你的字符串,因为它比仅使用scanf()更安全,并假设用户不会出错或意外或错误。

Enter values for A, B, C, in the format: "A B  -  C"
1 2 3
Values: A:1, B:2, C:0

Enter values for A, B, C, in the format: "A B  -  C"
1 2  -  3
Values: A:1, B:2, C:3

现在,考虑最后一次运行:您将看到scanf()将多个连续的空白字符压缩为单个字符,因此这些最终运行实际上成功的原因是:

Enter values for A, B, C, in the format: "A B  -  C"
1 2 - 3
Values: A:1, B:2, C:3

Enter values for A, B, C, in the format: "A B  -  C"
1     2           -                     3
Values: A:1, B:2, C:3