这段代码中
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);
函数实际上是如何工作的?
scanf 格式中的空白字符会导致它显式读取并忽略尽可能多的空白字符。因此,对于
scanf("%d ", ...
,在读取一个数字后,它将继续读取字符,丢弃所有空白,直到它在输入中看到一个非空白字符。该非空白字符将保留为输入函数要读取的下一个字符。
使用您的代码:
printf("enter a value for j ");
scanf("%d ",&j);
printf("j is %d \n", j);
它会打印第一行然后等你输入一个数字,然后继续等待数字后面的东西。因此,如果您只输入 5Enter,它会出现挂起——您需要输入另一行带有一些非空白字符的字符才能继续。如果您随后键入 6Enter,这将成为
i
的值,因此您的屏幕将如下所示:
enter a value for j 5
6
j is 5
enter a value for i i is 6
此外,由于大多数 scanf %-转换也会跳过前导空格(除了
%c
、%[
和 %n
),空格).所以在大多数情况下,你应该避免在 scanf 转换中使用空格,除非你知道你特别需要它们来实现它们的特殊效果。
格式字符串中的空白字符(空格、换行符、水平和垂直制表符)匹配输入中任意数量的空白字符。在你的第一个案例中
"%d"
" %d"
然后它会吃掉用户输入的所有空白,包括
scanf("%d ",&j);
按Enter
并且它会期望输入一个非 WSC 。在这种情况下,您的程序将通过按
Ctrl+
Z终止。
' '
格式中的空白字符匹配任意数量的空白字符,如 \n
scanf
消耗掉。
区别(虽然很明显)是不同的格式字符串。如果您输入以下行:
isspace
scanf
会成功返回。否则,这取决于您提供的输入。
"3 "
基本上跳过空格(制表符、空格、换行符),并在输入流中搜索字母数字值。由于这是尾随空格,当按下 ENTER时,它会与输入末尾的尾随换行符混为一谈,因此影响不大。
scanf()
期望提供的输入与您提供给它的格式字符串完全匹配,除了连续的空白字符被压缩为单个空白字符。如果你想用它的字符串处理等价物来解析大数据字符串,这就变得非常重要,scanf()
.
进一步测试的一个很好的练习是这样的:
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
之类的东西从用户那里获取输入字符串,然后使用各种搜索函数(即:strstr()、strch()、strcat、strcpy 等)来解析您的字符串,因为它比仅使用
scanf()
并假设用户不会无意或故意犯错要安全得多。fgets()
现在,考虑最后一次运行:您会看到
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