黑马程序员技术交流社区

标题: scanf(),getchar(),gets()使用对比 [打印本页]

作者: 綦敦涛    时间: 2015-4-12 20:12
标题: scanf(),getchar(),gets()使用对比
本帖最后由 綦敦涛 于 2015-4-12 20:12 编辑



问题一: 使用scanf 和 getchar()函数读取字符
先来看两个简单的程序,用来读字符,并且输出:
  1. #include <stdio.h>
  2. int main()
  3. {
  4.     char ch1,ch2;
  5.     scanf("%c",&ch1);
  6.     scanf("%c",&ch2);
  7.     printf("%d %d\n",ch1,ch2);
  8.    
  9. //   或者:
  10. //     char ch3,ch4;
  11. //     ch3 = getchar();
  12. //     ch4 = getchar();
  13. //     printf("%d  %d\n",ch3,ch4);

  14.      return 0;
  15. }
复制代码


          程序的本意是从键盘输入两个字符,并打印相应的ASCII码,但是运行后回发现,当输入a回车后并不会提示继续输入第二个字符,而是直接输出 97,10 。
分析:
程序的输入都有一个缓冲区,即输入缓冲区,当由键盘输入是会将输入的内容放入输入缓冲区,c程序直接从输入缓冲区读数据,所以当缓冲区中有残留数据时,程序并不会提示继续输入,而是直接取走缓冲区残留的数据。scanf和getchar读取缓冲区的数据,当输入a并回车后,其实'a'和’\n'都会存入内存缓冲区,所以第一次读取'a'被取走,剩下的‘\n'被第二次取走,输出的10恰好是'\n'的ASCII值。

问题二:使用scanf读取字符串
先看程序:
  1. #include <stdio.h>
  2. int main()
  3. {
  4.     char ch1[20],ch2[20];
  5.     scanf("%s",ch1);
  6.     printf("%s\n",ch1);
  7.    
  8.     scanf("%s",ch2);
  9.     printf("%s\n",ch2);
  10.    
  11.     /*
  12.      
  13.      char *ch3,*ch4;
  14.      scanf("%s",ch3);
  15.      printf("%s\n",ch3);
  16.      
  17.      scanf("%s",ch4);
  18.      printf("%s\n",ch4);
  19.      */
  20.    
  21.     return 0;
  22. }
复制代码


分析:
程序功能是读取字符串并输出,这是可以实现的,前提是字符串中间不能有空格或者tab,因为scanf函数是遇到空格、tab、回车停止读取,比说说,我们输入ab  cd,
第一个scanf会去读ab,而cd还在缓冲区中,第二个scanf就会读取cd,而不是要求用户继续输入。
P.S.  虽然定义字符串也可以用指针的方法,但是这里如果用指针定义,程序不会正确执行,原因不清楚。所以我注释的程序是由问题的。

问题三:使用gets()读取字符串
上面的程序,我们把scanf改成gets()来看一下执行结果:
  1. #include <stdio.h>
  2. int main()
  3. {
  4.     char ch1[20],ch2[20];
  5.     gets(ch1);
  6.     printf("%s\n",ch1);
  7.    
  8.     gets(ch2);
  9.     printf("%s\n",ch2);
  10.    
  11.     return 0;
  12. //    输入:hello world
  13. //    输出:hello world
  14. //    输入:world piece
  15. //    输出:world piece
  16. }
复制代码

分析:程序结果与scanf显然不同,当输入带有空格的字符串,程序照样会正确读取,所以当我们需要需要带有空格的字符串是,可以选择使用gets()方法;
P.S.   scanf()函数同样可以实现读取带空格的字符串,格式是scanf("%[^'\n']);  (什么意思,不清楚)

总结:
scanf:  以空格、tab、 回车结束一次读取,不会舍弃最后的回车符;
getchar(): 以enter结束输入,也不会舍弃回车符;
get():  以Enter结束,接收空格,舍弃回车符;

避免出现问题:需要清空一下缓冲区的残留数据:
我知道的是rewind(stdin);
使用方法:在第一次读取语句后加rewind(stdin)即可清除上次读取结束后残留的缓冲区数据;

上个帖子搞乱了,重新发下。有问题,有错误,尽情反馈!!:lol





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2