C语言:关于scanf函数输入问题

#include <stdio.h>
问题:
1.scanf函数以什么为截取字符的信号啊?空格?tab?回车?还是根本就没有啊?
2.下面的程序再输入Aa时就没有用到空格,这是难道编译器就能够正确的截取吗?
3.在输入三个连续的字符时就用到了空格,是因为他们是相同的数据类型吗?如果在输入第一个实数后面输入一个字符是不是就不用空格了啊?
main()
{
int a,b;
float x,y,z;
char c1,c2;
scanf("%5d%5d%c%c%f%f%*f,%f",&a,&b,&c1,&c2,&x,&y,&z);
printf("a=%d b=%d x=%.1f y=%.2f z=%.1f c1=%c c2=%c",a,b,x,y,z,c1,c2);

}

你首先要明白,从键盘读入键盘缓冲区(buffer)的数据都是以ASCII码存储的(包括回车)。
程序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;i<2;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;i<2;i++)
scanf(" %c",&j);/*注意这里%前有一个空格*/
printf("%d",j);
}
1<回车>2<enter>的情况:
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里面已经没有数据了,要求键盘输入:2<enter>.
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");
}
温馨提示:内容为网友见解,仅供参考
第1个回答  2010-11-26
如果前面引号里的格式控制符间用的是什么符号,那么你输入的时候也要用同样的符号来分割,例如scangf("%d,%d",&a,&b);那么你输入a,b的时候要用“,”来分割,否则编译错误或者得不到正确答案。如果不加任何符号的话,就默认是空格或者 Tab,回车也可以的。
第2个回答  2010-11-26
scanf函数在输入 字符串 时遇空格,制表符就停止
第3个回答  2010-11-26
1.这个要看你的程序怎么写的同时需要什么样的数据类型。
2.对,编译器的确能自动识别数据类型,所以当你要输入的全是数字型时,遇到空格,回车就自 动结束了,开始下一个数的输入。但当你要输入字符或者字串是就需要用程序控制了,否则空格会被当做是一个字符写入。
3.上面2已经回答了。
你这个正确的写法是(都用空格表示结束标志)
输入字符时加空格(在第一个%c的两边)表示结束标志,本来其他也要加空格表示结束,但因为都是数字型,输入空格时编译器就当做结束标志了。

C语言中scanf函数的3种常见问题与应对技巧你都会了吗?
1. 空白符问题 在输入数据时,如果在整数后面输入了一个空格或回车符,程序可能会出错。这是因为scanf函数在读取到空白字符后会跳过这些字符继续读取下一位。解决方法是确保在整数后没有额外的空白符。例如:int a;输入:5(不包含空格或回车)输出:5 避免在整数输入后添加空格或回车,以防止scanf跳过...

C语言中用scanf函数输入字符时,为什么要在输入控制符%c前面加空格?用s...
C语言中的scanf函数主要用于从标准输入流中读取数据,其基本格式是scanf(“输入格式”,“输入地址”)。对于字符串的读取,虽然理论上可以通过定义字符指针并逐个读取字符,但在实践中,特别是处理用户输入时,理解并正确使用scanf的特性是至关重要的。总的来说,添加空格到scanf的输入格式是提高代码健壮性...

C语言scanf输入时可以加逗号的吗?
结论是,C语言的scanf函数在输入数据时,确实可以使用逗号来分隔不同的数据类型,但这需要确保输入的格式与scanf的格式控制字符串匹配。例如,当你使用scanf("%d,%d", &a, &b);时,输入的整数必须用逗号分隔,而不能用空格或回车。然而,对于scanf("%d%d", &a, &b);这样的格式,空白字符(空格...

scanf函数输入问题
scanf ("%ul%d",&a,&number)这个函数没有返回值,当然跟2比较不会等于了,所以这样永远不会有输出 你的意思是输入的第一个数2就是函数scanf ("%ul%d",&a,&number)整体的返回值,但是实际上scanf()函数是不会返回输入的第一个数的,他没有返回值,当然也就不会等于2了,...

C语言scanf函数输入时键盘缓冲区\\n的问题
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语言关于scanf函数问题
第一个问题,因为你的scanf函数使用了域宽来指定读入的格式。所谓域宽,就是说读入的时候把某个宽度内的值付给某变量。那么。你第一个参数读入规则是%3c,意思是设置域宽为3,读入一个char型数据。你输入的是abcde。那么前面的abc将作为第一个参数给一个char型数据。而char型数据只需要一个字符,所以a...

scanf函数 字符串输入问题
1. scanf在用%s时,是指输入一个字符串,不用&,因为字符数组的名字本身就代表是这个数组的首地址,已经是地址了,再加&就错误了。2.用%c时,是输入一个字符,那么这个字符必须加&,才能放入相应字符变量的地址里,这是不加&,也错了。

C语言中用scanf函数输入字符时,为什么要在输入控制符%c前面加空格?用s...
例如:scanf(" %c" ,&c),你输入了' a'(a前面有个空格),a就能被c接受。但控制符前如果没空格,那c就接受了空格,这个可以防止误操作,忽略空格输入,接受第一个非空格输入。注意事项:对于scanf()而言,%c是个较为特殊的说明符。 %c前没空格,scanf()将读取标准输入流中的第一个字符,%c...

C语言的scanf问题
scanf("%c%c%c",&c1,&c2,&c3); 输入:a□b□c↙ 结果:a→c1,□→c2,b→c3 (其余被丢弃)scanf()函数接收输入数据时,遇以下情况结束一个数据的输入:(不是结束该scanf函数,scanf函数仅在每一个数据域均有数据,并按回车后结束)。 ① 遇空格、“回车”、“跳格”键。 ② 遇宽度结束。 ③ 遇非法...

c语言scanf的用法
scanf()是C语言中的一个输入函数。与printf函数一样,都被声明在头文件stdio.h里,因此在使用scanf函数时要加上#include<stdio.h>。(在有一些实现中,printf函数与scanf函数在使用时可以不使用预编译命令)它是格式输入函数,即按用户指定的格式从键盘上把数据输入到指定的变量之中。函数的第一个参数...

相似回答