快上网专注成都网站设计 成都网站制作 成都网站建设
成都网站建设公司服务热线:028-86922220

网站建设知识

十年网站开发经验 + 多家企业客户 + 靠谱的建站团队

量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决

c语言scanf函数缓冲 scanf缓存

C语言scanf函数输入时键盘缓冲区\n的问题

你首先要明白,从键盘读入键盘缓冲区(buffer)的数据都是以ASCII码存储的(包括回车)。

成都创新互联-专业网站定制、快速模板网站建设、高性价比甘南网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式甘南网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖甘南地区。费用合理售后完善,10多年实体公司更值得信赖。

程序1

#include "stdio.h"

void main()

{

char a;

char b;

scanf("%d",a);

scanf("%d",b);

printf("%d %d",a,b);

}

键盘输入

97回车

第一次回车后,buffer中的ASCII:39h,37h,0AH(0A是换行的ASCII), scanf会根据格式字符串中的第一个%d对buffer按字节顺序读取,当读取到0A时,认为%d型的数据结束,此时把已经读取到的39h,37h依据%d转为整型数据97存储在字符型变量a中。(这里是除去了扫描截止点0AH)

此时buffer中已经无任何数据了。

96回车

第二次回车后,按同样的流程,scanf会根据格式字符串中的第二个%d对buffer按字节顺序读取。最终b得到96.

此时buffer中已经无任何数据了。

输出

97 96

程序2

#include "stdio.h"

void main()

{

char a;

char b;

scanf("%c",a);

scanf("%c",b);

printf("%d %d",a,b);

}

键盘输入

9回车buffer:39H,0AH

因为scanf会按照第一个%c格式扫描buffer(只扫描一个字节就结束),然后把扫描到的39H直接送到变量a(当以%d格式读出来时,39H就是57)

此时,buffer中只有:0AH。

然后,scanft又遇到第二个%c,继续扫描buffer,得到0aH并送入变量b.

此时buffer中已经无任何数据了

输出

57 10

程序3

#include "stdio.h"

void main()

{

char a[100];

char b[100];

scanf("%s",a);

scanf("%s",b);

printf("%s %s",a,b);

}

键盘输入

abc回车

第一次回车后,buffer:61H,62H,63H,0AH。

scanf会按照%s的格式对buffer按字节顺序扫描,当扫描到0AH时,结束扫描(按照%s的要求,空格20H也是扫描结束点)。

然后把扫描到的(除去最后一个判断扫描截至的字节0AH)数据直接送入以a为起始地址的字符串。

此时,buffer无任何数据了。

def回车

第二次回车后,buffer:65H,66H,67H,0AH.扫描的流程与上面的完全一致。

输出

abc def

程序4

#include stdio.h

void main()

{

int i;

char j;

for(i=0;i2;i++)

scanf("%c",j);/*注意这里%前没有空格*/

printf("%d",j);

}

键盘输入

1回车,

这里scanf执行了两次(i==0时,与i==1时),而且每次都是想对j赋值。

第一次scanf,按%c的要求,只扫描buffer中的一个字节,但是buffer中并不数据,于是要求键盘输入数据到buffer,此时的1回车代表向buffer中输入了:31H,0AH。

然后按%c的要求,只扫描buffer中的一个字节:31h,并将它直接送入变量j.

此时,buffer中还留下:0AH。

第二次scanf要求键盘输入数据,按%c的要求,只扫描buffer中的一个字节:0Ah,并将它直接送入变量j.

此时,buffer无数据了。

最后,你用%d格式输出j的值(0AH换成整型就是10)

输出

10

程序5

#include stdio.h

void main()

{

int i;

char j;

for(i=0;i2;i++)

scanf(" %c",j);/*注意这里%前有一个空格*/

printf("%d",j);

}

1回车2enter的情况:

scanf会按照格式控制字符串的要求,顺序扫描buffer.

但是你其中有一个空格,这个很特殊,我也是第一次发现这个问题(一般我都不会在scanf中加入任何常量字符)

我测试了一下:我发现这个空格有吸收回车(0AH)和空格(20H)的“神奇功效”,吸收之后再要求buffer给一个字节,直到这个字节不是0AH或者 20H,此时把这个字节交给下一个格式字串。

第一次循环时遇到格式字串空格,就扫描buffer中的一个字节,但是buffer中无数据,要求从键盘输入数据:1〈回车〉,buffer中有数据了——31H,0AH。再读取到字节31H,scanf发现这个并不是0AH/20H,就把这个字节31H交给格式字符%c处理。

循环结束,此时buffer里面还有:0AH.

第二次循环时遇到格式字串空格,就扫描buffer中的一个字节——0AH,发现是0AH/20H,于是就要求buffer再来一个字节。此时buffer里面已经没有数据了,要求键盘输入:2enter.

buffer中有数据了——32H,0AH。于是再读一个字节31H,scanf发现这个并不是0AH/20H,就把这个字节32H交给格式字符%c处理(j最终得到32H)。

循环结束,此时buffer里面还有:0AH.

这里有一篇关于Printf的帖子:

程序6

#include "stdio.h"

void main()

{

int a;

int b;

scanf("%c",a);

scanf("%c",b);

printf("%d %d",a,b);

}

键盘输入

1回车

问题5:

你的编译器VC认为%d数据应该是4个字节,但是你采用的是%c读数据,

scanf("%c",a);此句读到的是1的ascii码:31h.然后把31H直接送入地址a(而并没有改写a的三个高字节地址)。

scanf("%c",b);同理。

你可以用printf("a=%x,b=%x\n",a,b);来验证我说的。它们的最低字节肯定是31H,0AH。

PS1:

当你把 int a;int b;放在main()外进行定义时,a,b的初值就是0。此时你会得到正确的结果。

当你把 int a;int b;放在main()内进行定义时,a,b不会被初始化(它们的三个三个高字节地址的内容是不确定的),你就会得到上面错误的结果。(定义的动态变量都不会被初始化,静态变量会被初始化为0)

PS2:以下也是不正确的用法。

char c;

scanf("%d",c);/当你用%d给c赋值时,会对从&c开始的连续4个字节进行赋值。当从buffer得到的值是在一个字节范围内(-128~127),下面是可以正常输出的。但是不管怎样,这样做是很危险的——越界。

printf("%d",c);

=================请你测试下这个程序========================

#include "stdio.h"

void main()

{

char c[4],i=4;

scanf("%d",c);/*请输入258回车*/

while(i--0)

printf("%02x ",c[i]);

printf("\n");

}/*如果得到的结果是00 00 00 01 02就说明我的结论是正确的(258的转为16进制数就是00 00 01 02H,然后scanf会把这个数放入以c为起始地址的)

================以下程序也是======================

#include "stdio.h"

void main()

{

char c,i=4;

char *p=c;

scanf("%d",c);/*请输入258回车*/

while(i--0)

printf("%02x ",p[i]);

printf("\n");

}

c语言,scanf函数,在输入一个数据时,如何使数据进去缓冲区?

关于清空缓冲区,举例如下:

#includestdio.h

int main()

{

int x;

scanf("%d", x);

fflush(stdin);  //清空输入缓冲

scanf("%d",x);//清空缓冲区后继续输入

printf("%d\n",x);

return 0;

}

关于C语言scanf函数的一个问题

%d后面的空格是用来匹配所有的连续空白字符的(空白字符包括空格 \t \n)直到碰到不是空白的字符。

这个用法主要是为了匹配输入时的空白符,举个例子:

int a;

char c;

scanf("%d",a);

scanf("%c",c);

上面这个输入代码里,如果是分两次输入(用空白分割),那么c是没有机会输入的,尤其是从文件读取的时候,会有很多的空白符,c会读取到缓冲区的空白,一般解决这个问题是再用一句gtechar(), ,但如果有很多空白就比较麻烦(文件里这种情况很多),如果在%d后面加个空格,就可以吧剩下所有的空白符给吸收掉:

int a;

char c;

scanf("%d ",a); //这样可以把空白吸收掉

scanf("%c",c);

在你这个代码里,输入全是%d格式,那这个空格就没必要了,不如去掉


当前文章:c语言scanf函数缓冲 scanf缓存
本文URL:http://6mz.cn/article/dogdpop.html

其他资讯