Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1483747
  • 博文数量: 181
  • 博客积分: 3308
  • 博客等级: 中校
  • 技术积分: 2227
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-03 12:03
个人简介

我是zoro

文章分类

全部博文(181)

文章存档

2015年(1)

2013年(35)

2012年(39)

2011年(50)

2010年(56)

分类: LINUX

2010-10-13 11:57:56

    这几天一直做一个项目,遇到了一个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) |
0

上一篇:线程池

下一篇:我的vim简单配置

给主人留下些什么吧!~~

chinaunix网友2011-01-02 19:30:27

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com

chinaunix网友2011-01-02 19:30:14

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com