zoukankan      html  css  js  c++  java
  • scanf函数具体解释与缓冲区

    1.基本信息

    函数原型

    int scanf( char *format, args, ...);

    函数返回值

           读入并赋给args的数据个数。遇到文件结束返回EOF,出错返回0。

    函数功能

           scanf函数是格式化输入函数,它从标准输入设备(键盘)读取输入的信息。按format指定的格式输入数据给args所指向的内存单元。

    调用格式

           scanf("格式控制字符串",地址表);

    int a, b;	
    scanf("%d%d",&a,&b);//输入10 12

    当中格式控制串由三类字符构成:格式化说明符、空白符、非空白符

    1 格式化说明符

         %c    读入一个字符                                                                                            

         %d    读入十进制整数                 

         %f     读入一个浮点数                

         %o    读入一个八进制整数        

         %x     读入十六进制整数  

         %s    读入一个字符串 

         %p    读入一个指针

         %[]    扫描字符集合,输入的字符属于方括号内字符串中某个字符。则提取该字符,否则结束提取

         %[^]   扫描字符集合。输入的字符属于属于方括号内字符串中的某个字符,结束提取

    2 空白字符

          空白字符会使scanf()函数在读取操作时略去输入中的一个或多个空白字符,空白字符能够是space,tab,newline,直到第一个非空白字符出现为止。

    之所以被称为空白字符是由于它们被打印出来时,在页面上出现的是空白而不是各种记号。

    3 非空白字符

           非空白字符会使scanf()函数在读取时剔除与之同样的非空白字符。

    2. scanf函数的注意事项

            1. scanf函数中"格式控制"的后面应该是变量地址

            2. 假设在“格式控制”字符串中除了格式说明符还有其他字符。则在输入数据时在相应的位置输入与之同样的字符

            3. 在用“%c”格式输入字符时。空白字符(space,tab,newline)和“转义字符”都作为有效字符输入。

            4. 在用“%s”格式输入字符时,输入的字符串中含有空白字符(space,tab,newline)。字符串读取结束。

            5. 在输入数据时。遇到下面情况时觉得该数据结束

                 (1) 遇到space。newline,Tab键;

                 (2) 按指定的宽度输入;

                 (3) 遇到非法输入;

    3 清除键盘缓冲区

           键盘缓冲区,是计算机输入过程重要环节。它是一个环形队列。用来暂时保存从键盘输入的字符。共32字节。

    补充说明:

           ‘Enter回车键’包括1个字符是‘ ’’;

    方法1:

    int c;
    while ( ( c = getchar() ) != '
    ' && c!= EOF)
    {
    	;
    }

           不停的使用getchar()获取缓冲区字符,直到获取的字符是换行符' '或文件结尾EOF为止,这种方法能够完美清除输入缓冲区,而且具备可移植性

    方法2:

    fflush( stdin );
    刷新标准输入缓冲区,也就是丢弃缓冲区中的内容。(非标准)

    4  错误案例分析

    4.1 參数输入不匹配

    	int data = -1;
    
    	while (1)
    	{
    		printf("1:
    2:
    3:
    4:
    0:
    input sever:");
    		scanf("%d",&data);//输入不是整数data值不改变
    		
    		switch (data)
    		{
    			case 1:  printf("1
    ");break;
    			case 2:  printf("2
    ");break;
    			case 3:  printf("4
    ");break;
    			case 0:  break;
    			default: printf("default
    ");
    		}
    
    		if (data == 0)
    		{
    			break;
    		}
    	}//end of while

    问题:

           当不小心输入了一个字符。而不是数据时。程序进入死循环。不断输入printf函数的内容。

    分析:

          因为scanf("%d",&data)要求參数是个整数,而实际输入却为字符,參数不匹配scanf结束data的输入。

    函数继续运行。

    当再次运行到scanf函数时。此时输入缓冲区中有内容。直接从缓存中读取不再等待人为输入。故出现死循环。屏幕不再有等待输入提示

    办法:

           在scanf函数后加入fflush(stdin)就能够解决这个问题了。

    由于每次输入数据时缓冲区都被刷新,每次都会等待输入。

    4.2 scanf输入中不能有空格的问题

    	char str[80];
    
    	scanf("%s",str);
    	printf("str = %s
    ", str);

    问题:

           当输入的字符中有空格时,输出不完整。

    分析:

          %s格式字符遇到空格时结束读取。兴许的字符不再读取储存。

    办法1:

           scanf函数改写为:scanf("%[^' ']",str);

    办法2:

            使用gets函数,关于gets函数见:gets()函数具体解释与缺陷

    4.3 %c和缓冲区问题

    char str[5];
    
    for(int i = 0; i < 4; i++) 
    {
    	scanf( "%c",&str[i]);
    }
    
    str[4] = ''; 
    printf("str:%s
    ",str); 

    问题:

          当输入a回车b回车。函数运行结束。

    分析:

         因为scanf按%c格式输入,当输入a并按回车时输入缓冲区中的内容是'a'和' ',分别给了str[0]和str[1]。相同输入b时也是如此。刚好4个字符结束输入。

    str字符数组的内容各自是'a'、' '、'b'、' '、''。

    办法1:

           在scanf函数后面加入语句:fflush(stdin);

    办法2:

           使用gets函数。


  • 相关阅读:
    jQuery的$.extend
    es5中的严格模式理解(‘use strict’)
    微信小程序制作下拉列表
    微信小程序之路由
    微信小程序自定义弹窗
    微信小程序小总结
    npm link的使用
    vue 全局变量的处理方式
    大屏项目屏幕分辨率适配
    git flow的使用
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7264097.html
Copyright © 2011-2022 走看看