scanf()函数对字符输入的一些问题

在c库中包含了很多输入函数,scanf()是最通用的一个,因为它可以读取不同格式的数据。scanf()使用空白(换行符,制表符,空格)把输入分成多个字段。依次把转换说明和字段匹配时跳过空白。但是在字符的转换说明时。根据%c,scanf()会读取每个字符,包括空白

关于scanf()函数我们要知道以下几点:

1、用户输入的字符,会以ASCII码形式存储在键盘缓冲区;

2、每调用一次scanf函数,就从键盘缓冲区读走一个字符,相当于清除缓冲区;

3、若用户一次输入n个字符,则前n次调用scanf函数都不需要用户再次输入,直到把缓冲区的数据全部读取(清除)干净;

4、调用scanf()函数时,用户最后输入的回车也会储存在键盘缓冲区;


实例一:

# include <stdio.h>
  
 int main()
{
    char c;
    scanf("%c", &c);
    printf("%d\n", c);
  
    scanf("%c", &c);
    printf("%d\n", c);
     
    return 0;
 }
 
 /*
 程序在VC++6.0中的显示结果是:
 1
 49
 10
 */

我们发现在输入1时,会连续输出49和10,这是因为1的ASCII码值为49,回车的ASCII码为10,回车也是一个字符,所以被第二个scanf和printf输入输出了。(一定要清楚的理解缓冲区的概念)

解决方法:

1.在第8行加入fflush(stdin);//清空输入流缓冲区的字符

可以通过清空缓冲区,在printf()函数输出缓冲区中我们输入的第一个字符后清空缓冲区,从而避免输出回车符

2.将scanf("%c", &c);替换为scanf(" %c", &c);

在格式字符串中空格放在%c前,从第一个非空白字符开始读取。(空白字符包括换行符,制表符,空格,scanf()内使用格式字符串和参数列表

3.在第8行加入getchar。

用getchar再取一次回车符。

实例二:关于scanf函数接受键盘的细节

#include <stdio.h>

int main() 
{    
   int a = 0, b =0;
   char d = 'a', e ='a';
   scanf("%d",&a);        //输入字符a到缓存,跳过接受,a=0
   scanf("%d",&b);        //输入字符a到缓存,跳过接受,b=0
   scanf("%c",&d);        //输入字符a到缓存,接受,d=b
   scanf("%c",&e);        //e接受换行符,ASCII为10
   printf("%d,%d,%c,%d\n",a,b,d,e);
   return 0;
}

/*
程序在VC++6.0中的显示结果是:
b
0,0,b,10
*/

当我们输入b后,执行第一个scanf函数,b为字符型,而读取类型为%d整型,所以跳过接受,同理第二个scanf函数也跳过接受,此时缓冲区内有两个字符分别是‘b’和换行符,第三个scanf函数接受‘b’,第四个scanf函数接受换行符。所以输出结果为0,0,b,10。(如果在声明的时候没有对a,b赋值,则在输出a,b时会输出垃圾值)。


实例三:

# include <stdio.h>
int main()
{
    int a = 1;
    char b = 'b';
    scanf("%d%c", &a, &b);
   
    printf("%d\t%c\n", a, b);
    
    return 0;
}

输入:a8c  输出:1b

我最初预想的输出为8c,其实不然,第一个scanf函数中%d失败后这条语句就结束了,而不会继续%c,缓冲区还是a8c,从而输出结果为1b。




参考:https://www.cnblogs.com/shuaishuaidefeizhu/p/5886899.html

猜你喜欢

转载自blog.csdn.net/qq_41282102/article/details/80246701