关于C语言中的scanf的一些小技巧
在 PAT Basic Level 1009 说反话 中,我们使用了scanf输入了一串带空格的字符串。通常scanf是不能输入空格的,因为某些情况下scanf遇到空格会结束输入。具体后面讲。
通常这样使用 scanf("输入格式",&变量名)
,输入格式可以是%d
,%c
,%f
等,分别代表输入int
,char
,float
类型的变量。
&
是地址运算符。当输入格式为%s
,即输入字符串的时候不需要取地址符&
,C语言中数组名就代表了其地址。
对于如下一段代码
#include<stdio.h>
int main(){
char str[10];
scanf("%s",str);//注意这里没有加取地址符&
printf("%s\n",str);
return 0;
}
输入:eacryo eac
输出:earyo
按照%s输入字符串的时候,遇到空格就终止输入,即scanf("%s",array)
的情况下,scanf遇到空格认为一次输入结束。因此输入字符串不能带空格。
再看如下示例:
#include<stdio.h>
int main(){
char c1,c2,c3;
scanf("%c%c%c",&c1,&c2,&c3);//注意这里有取地址符&
printf("%c,%c,%c\n",c1,c2,c3);
return 0;
}
输入:e a
输出:e, ,a
说明%c
输入的时候空格会输入。
但如果我们稍微改动一下:
#include<stdio.h>
int main(){
char a,b;
scanf("%c %c",&a,&b);
printf("%c %c",a,b);
return 0;
}
输入:e a
输出:e a
在这种情况下空格不会被读入b。
但如果碰到循环,情况又不一样的了。
#include<stdio.h>
int main(){
int n,i;
char a,b;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%c %c",&a,&b);
printf("i=%d a=%c b=%c\n",i,a,b);
}
return 0;
}
输入:2
e a
输出:
i=0 a=
b=e
i=1 a= b=a
第一个a居然读入了回车
,第一个b读入了e
,第二个a读入了空格
,第二个b读入了a
。说明scanf()
以%c
读入数据的时候,由于缓冲区有回车,读入的数据会非常奇葩。我们在scanf("%c %c",&a,&b);
这一行前面加一行getchar();
用来吃回车。这样的就正常了。
#include<stdio.h>
int main(){
int n,i;
char a,b;
scanf("%d",&n);
for(i=0;i<n;i++){
getchar();
scanf("%c %c",&a,&b);
printf("i=%d a=%c b=%c\n",i,a,b);
}
return 0;
}
输入:
2
e a
c r
输出:
i=0 a=e b=a
i=1 a=c b=r
(实际上输入和输出是交错出现在屏幕上的,我把它们分开写是为了看起来更直观)
如果要用%s的形式1输入空格该怎么办?答案是在scanf中使用正则表达式。scanf("%[^\n]",str)
中[]
内是匹配的字符,^
表示求反集。当只有遇到 \n
即回车才结束输入。