这几天一直做一个项目,遇到了一个BUG,scanf和getline不阻塞等待我输入,反而直接跳过运行了。经过调试,发现其并没有直接跳过,而是接收了一个字符'\n'。因为程序中要经常从键盘输入信息,故产生的一个野'\n'字符。下面把scanf的一些相关特点用代码表示出来吧,以备遗忘。
int main(void)
{
char a,b;
scanf("%c",&a);
scanf("%c",&b);
printf("a=%c,b=%c",a,b);
}
|
运行结果:
zx@zhangxu:~/2/test$ ./test
a
a=a,b=
zx@zhangxu:~/2/test$ ./test
a b
a=a,b= zx@zhangxu:~/2/test$
|
可以看出,第一次scanf遗留一个野'\n',被第二个scanf接收。
再以字符串为例:
int main(void)
{
char a[32],b[32];
scanf("%s",a);
scanf("%s",b);
printf("a=%s,b=%s",a,b);
}
|
运行结果:
zx@zhangxu:~/2/test$ ./test
abcdefg
fijklmnop
a=abcdefg,b=fijklmnopzx@zhangxu:~/2/test$ ./test
abcdefg hijklmnop
a=abcdefg,b=hijklmnopzx@zhangxu:~/2/test$
|
从结果看出,字符串也是不接收结尾的'\n',第二次运行看出‘ ’隔开了两个字符串。若想得到包括空格‘ ’的字符串,可以用scanf的[]类型,如下:
int main(void)
{
char a[32],b[32];
scanf("%[^\n]",a);
scanf("%s",b);
printf("a=%s,b=%s",a,b);
}
|
运行结果:
zx@zhangxu:~/2/test$ ./test
just a coder
just a coder
a=just a coder,b=justzx@zhangxu:~/2/test$
|
对于遗留的'\n'处理:
int main(void)
{
char a[32],b[32],c,d;
scanf("%[^\n]",a);
c=getchar();
scanf("%s",b);
d=getchar();
printf("a=%s,c=%c,b=%s,d=%c",a,c,b,d);
}
|
运行结果:
zx@zhangxu:~/2/test$ ./test
just a
coder
a=just a,c=
,b=coder,d=
zx@zhangxu:~/2/test$ ./test
|
对于这个问题,也顺便测试了一下getchar,gets,fgets这几个函数。
getchar()等价于getc(stdin)从stdin读一个字符。
gets(标准输入读)从stdin读一行字符串,而且它是不接收'\n',也不会遗留'\n'。gets与fgets的一个不太注意区别是:“gets并不将换行符存入缓冲区”,这一特点在一下的实例中可以体会到。int main(void)
{
char a[10],c;
gets(a);
c=getchar();
printf("a=%s,c=%c",a,c);
}
|
运行结果:
zx@zhangxu:~/2/test$ ./test
just a
coder
a=just a,c=czx@zhangxu:~/2/test$
|
但gets是不建议使用的函数,因为在使用gets时不能指定缓冲区的长度,可能造成缓冲区溢出,产生不可预料的后果。fgets(指定流读):
原型:char *fgets(char *buf,int n,FILE *fp);
返回值:若成功则返回buf,若已到达文件结尾或出错返回NULL。
int main(void)
{
char a[10],c;
fgets(a,5,stdin);
c=getchar();
printf("a=%s,c=%c",a,c);
}
|
运行结果:
zx@zhangxu:~/2/test$ ./test
123456
a=1234,c=5zx@zhangxu:~/2/test$ ./test
1234
a=1234,c=
zx@zhangxu:~/2/test$ ./test
123
4
a=123
,c=4zx@zhangxu:~/2/test$
|
使用fgets是要比较注意的是指定缓冲区长度n的问题。该函数一直读到换行符为止,但是
不超过n-1个字符,读入的字符被送入缓冲区,缓冲区你null字符结尾。若该行(包括最后一个换行符)的字符数超过n-1,则fgets只返回一个不完整的行,但是缓冲区总是以null字符结尾。
阅读(3485) | 评论(2) | 转发(1) |