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函数。


原文地址:https://www.cnblogs.com/jinxiang1224/p/8468441.html