scanf()使用

在学习C语言的时候,printf()是我们学到的第一个函数,相信“hello world”这个例子大家都不会陌生吧,接着就是scanf()这个函数了,这个函数的功能是格式输入,它的函数原型是:

  int scanf(const char *format,…);

  这个函数的基本用法这里就不说了,这里介绍一些这个函数使用中常见的问题及解决方法:

  第一,连续输入两个或多个字符的时候,第二次输入直接跳过了如:

      int main()

  {

  char a,b;

  scanf(“%c”,&a);

  scanf(“%c”,&b);

  return 0;

  }

  输入 a回车 然后就退出了。

  这个问题有很多说法有说是缓冲区没有清除,有说stdin这个流的问题,这里我们不去追究,这里介绍几个解决这种问题的方法:

  int main()

  {

  char a,b;

  scanf(“/n%c”,&a);

  scanf(“/n%c”,&b);或 scanf(“ %c”,&b);%c前有空格

  return 0;

  }

  这次再编译一下就没有问题了。

  第二,使用scanf()函数输入一句话的时候,如:

  int main()

  {

  char string[50] ;

  scanf(“%s”,string);

  printf(“%s/n”,string);

  return 0;

  }

  输入:hello world!

  结果:hello

  显然这个结果没有达到我们的要求。

  解决方法:

  int main()

  {

  char string[50] ;

  scanf(“%[^/n]”,string);

  printf(“%s/n”,string);

  return 0;

  }

  重新编译一下,没有问题了吧!

  这里如果要是连续输入多个语句的话也会出现连续输入字符的那种问题,当然解决方法也相同了。

  这里是最常见的几个问题,可能还有其他的解决方法,希望和大家相互交流,能力有限有问题希望大家多多指教。

  “本文由华清远见http://www.embedu.org/index.htm提供”

<1>        本意:接收字符串. 
       写成代码:void main()
                 {
                 char *str;
                 scanf("%s",str);
                 printf("string is: %s/n",str);
                 }
   符合愿意代码:char *str=NULL;
                 str=malloc(128*sizeof(char) );
                 scanf( "%s/n", str );
           点评:指针需要你手动给它分配空间,并手动指向该空间如果没有,指针指向哪里,是不确定的
                 也就是说,你scanf得到的数据存放到哪里是不一定的因此,偶尔有运行正常是你运气好
                 错误才是正常的 
-----------------------------------------------------------------------
<2>        本意:接收输入的a,b值. 
       写成代码:int a,b;
                 scanf("%d%d",a,b);
   符合愿意代码:int a,b;
                 scanf("%d%d",&a,&b);
           点评:这是不合法的。Scanf函数的作用是:按照a、b在内存的地址将
                 a、b的值存进去。“&a”指a在内存中的地址。
------------------------------------------------------------------------
<3>        本意:在Input字符串后输入数值. 
       写成代码:int num;
                 Scanf("Input %d", & num);
     实际应输入:Input 1234 或者 Input1234
   符合愿意代码:int num;
                 printf("Input";
                 scanf("%d",&num);
------------------------------------------------------------------------  
<4>        本意:接收填入的数据. 
       写成代码:#include <stdio.h>
                 main()
                {
                 int num;
                 printf("please input the student's score: ";
                 scanf("%d",&num);

                 if((num<0)||(num>100))
                 {
                      printf("The score put isnt fine. please run and input again.";
                 }
                 else if(num>90)
                 {
                      printf("The grade is A.";
                 }
                
                 else if((num>80)&&(num<90))
                 {
                     printf(..................
                     .............
                 }
                 ..............
                        
                 }
     实际应输入:这个程序是没错,不过如果有人要存心捣乱, 输入时不是输入数字,而是其
                 他的什么字符,那么congratulations,这个程序崩溃掉了.
   符合愿意代码:#include <stdio.h>
                 main()
                {
                 int num,int result=0;
                 printf("please input the student's score: ";
                  
                 while(result==0)
                {
                 fflush(stdin);  /*  清空输入缓冲区. */
                 if(result!=1)printf("lease input a digital score: ";
                 result=scanf("%d",&num);  
                }
                ............................
                }
           点评:scanf函数执行成功时的返回值为成功读取的变量数,如果第一个变量的读取既告失败则返回值为0.   
                 我们可以通过判断scanf函数执行的返回值,  可以制止用户不正确地输入,从而控制程序的流程.
           另 :#include <stdio.h>
                 int main()
                {
                       char b[2];
                       scanf("%s", b);
                       printf("%s/n", b);
                }
                如果输入的字符比较多例如10个,就会seg fault,可见scanf是不安全的,没有检查缓冲区。
                同样,把上面的scanf换成gets,效果是一样的。(而且编译的时候有warning,不让用gets)。
                fgets是安全的,这样用法:
                fgets(b, 2, stdin);
                注意,这样子其实只读了一个字符,第二个字符是0。所以如果输入是sad,则b[0]='s', b[1]=0.
                由此可见,读入字符串时,fgets更安全。
------------------------------------------------------------------------                     
<5>        本意:接收带空格等的字符串. 
       写成代码:#include <stdio.h>
                 void main(){
                 char c[100];
                 scanf("%s", c);
                 printf("%s", c);
                 }
           输入:welcome to come here
           输出:welcome
   符合愿意代码:换用gets();
           点评:因为输入终端的buffer把空白字符(包括空格。/t等)当成字符串分隔符,
                 你用过命令行参数就明白了,main函数的参数是 int main(int,char*[])
------------------------------------------------------------------------  
<6>        本意:接收规定精度的数据. 
       写成代码:scanf("%7.2f",&a);
     实际应输入:
   符合愿意代码:
           点评:这样做是不合法的,输入数据时不能规定精度。
------------------------------------------------------------------------  
<7>        本意:正确输入a,b的值. 
       写成代码:#include <stdio.h>
                 int main()
                 {
                  int a,b,c;  /*计算a+b*/
                  scanf("%d,%d",&a,&b);
                  c=a+b;
                  printf("%d+%d=%d",a,b,c);
                 }
           现象:一旦输入了错误的类型,程序不是死锁,就是得到一个错误的结果。
   符合愿意代码:#include <stdio.h>
                 int main()
                {
                 int a,b,c;  /*计算a+b*/
                 while(scanf("%d,%d",&a,&b)!=2)fflush(stdin);
                 c=a+b;
                 printf("%d+%d=%d",a,b,c);
                }
           点评:scanf()函数执行成功时的返回值是成功读取的变量数,也就是说,
                 你这个scanf()函数有几个变量,如果scanf()函数全部正常读取,
                 它就返回几。但这里还要注意另一个问题,如果输入了非法数据,
                 键盘缓冲区就可能还个有残余信息问题。
------------------------------------------------------------------------  
<8>        本意:可以连续多次接受数据. 
       写成代码:#include <stdio.h>
                 int main()
                 {
                    int a;
                    char c;
                    do
                    {
                        scanf("%d",&a);
                        scanf("%c",&c);
                        printf("a=%d     c=%c/n",a,c);
                        /*printf("c=%d/n",c);*/
                    }while(c!='N');
                 }
           现象:scanf("%c",&c);这句不能正常接收字符
   符合愿意代码:#include <stdio.h>
                 int main()
                 {
                    int a;
                    char c;
                    do
                   {   scanf("%d",&a);
                       fflush(stdin);
                        scanf("%c",&c);
                        fflush(stdin);
                        printf("a=%d     c=%c/n",a,c);
                    }while(c!='N');
                 }      
           点评:我们用printf("c=%d/n",c);将C用int表示出来,启用printf("c=%d/n",c);这一句,
                 看看scanf()函数赋给C到底是什么,结果是 c=10 ,ASCII值为10是什么?换行即/n.
                 对了,我们每击打一下"Enter"键,向键盘缓冲区发去一个“回车”(/r),一个“换行"
                 (/n),在这里/r被scanf()函数处理掉了(姑且这么认为吧^_^),而/n被scanf()函数
                “错误”地赋给了c.
             另:fflush(FILE *stream)函数,其主要功能:可将所有缓冲区数据写入指定的流文件将
                 清空缓冲区。
------------------------------------------------------------------------  
<9>        本意:接收float型数值. 
       写成代码:#include "stdio.h" 
                main() 
                { 
                 int i=0; 
                 struct BOOK 
                  { 
                     char bookName[100]; 
                     float bookPrice; 
                  }; 
                  struct BOOK book[10]; 
                  for(i=0;i<10;i++) 
                  { 
                      scanf("%f",&book[i].bookPrice); 
                  } 
                } 
           现象:  编译通过,但运行时报错(TC3.0): 
                   scanf : floating point formats not linked. 
                   Abnormal program termination 。 
   符合愿意代码:#include "stdio.h" 
                main() 
                { 
                  int i=0; 
                 float t=0; 
                 struct BOOK 
                 { 
                    char bookName[100]; 
                    float bookPrice; 
                  }; 
                  struct BOOK book[10]; 
                  for(i=0;i<10;i++) 
                  { 
                      scanf("%f",&t); 
                      book[i].bookPrice=t; 
                  } 
                }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值