
scanf函数
-
2023年3月19日发(作者:微生物图片)C语⾔中scanf与分隔符(空格回车Tab)
1、scanf的返回值
scanf("%d%d",&x,&y);
如果x和y都被成功读⼊,那么scanf的返回值就是2;
如果只有x被成功读⼊,返回值为1;
如果x和y都未被成功读⼊,返回值为0;
如果遇到错误或遇到endoffile,返回值为EOF。
2、scanf的处理机制
scanf以删除的⽅式从缓冲区读⼊数据(来⾃标准输⼊设备的数据存储在缓冲区),也就是说,scanf从缓冲区读⼊⼀个数据项,该数据项在缓
冲区中就被清除掉了。⽽如果scanf需要读取⼀个数据项,返现缓冲区当前是空的,那么程序就会在scanf代码处阻塞,等待⽤户输
⼊,scanf函数接收到相应的数据项之后,在缓冲区中将这⼀数据项清除,scanf函数返回,程序继续执⾏。
3、scanf对不同类型输⼊的处理⽅式
⾸先,要清除⼀个概念:空⽩字符(whitespace)。⼀般,程序中所指的空⽩字符是指空格(space),回车(enter)和指标符(table)。
3.1整数%d
对于整型数据的输⼊,也就是说"%d"类型的输⼊,scanf默认的分割符是所有的空⽩字符(空格,回车和指标符都⾏)。也就是说如果⼀个
scanf函数中出现scanf("%d%d",&a,&b),那么⽤任何⼀个空⽩字符来分隔两个整数a,b的值,变量a,b都可以接收到正确的输⼊。另外,要
注意的是,scanf对于数字输⼊,会忽略输⼊数据项前⾯的空⽩字符.
3.2字符串%s
scanf对于字符串输⼊的处理和对整数类似,会忽略前导的空⽩字符,⽽且默认的分隔符是所有的空⽩字符。但是,要注意的是,由于C语
⾔中,没有string类型,都是⽤char型数组来表⽰。因此,scanf会为每⼀个输⼊的字符串最后加⼀个‘0’。下⾯是⼀个例⼦,可以看出
scanf这货的边界控制还是要⼩⼼。
3.3字符%c
scanf在处理对字符数据的输⼊时,既不会忽略前导空⽩字符,默认也没有任何分隔字符。所有的字符,包括空⽩字符都会被当成输⼊字
符。
由于缓冲区中有回车空格等数据,会导致输⼊数据⽐较诡异,为了解决这个问题,有以下⽅法:
(1)清空缓冲区
在微软系统中,有⼀个名为fflush(stdin)的函数,可以⽤来清空缓冲区,在freopen中fflush不要⽤
#include
intmain()
{
chara,b;
printf("Inputthevalueofaandb:");
while(scanf("%c%c",&a,&b)!=EOF)
{
printf("a=%c,b=%cn",a,b);
fflush(stdin);
printf("Inputthevalueofaandb:");
}
return0;
}
(2)将缓冲区的数据读出来
有的编译系统并没有定义stdin的fflush操作,这个时候,可以把缓冲区中的数据读出来,有如下⼏种可⾏的⽅法:
1)getchar()
将例4中的fflush(stdin);语句换成
charc;
while((c=getchar())!=’n’&&c!=EOF);
运⾏效果和上⾯的相同。
#include
intmain()
{
chara,b;
printf("Inputthevalueofaandb:");
while(scanf("%c%c",&a,&b)!=EOF)
{
printf("a=%c,b=%cn",a,b);
charc;
while((c=getchar())!='n'&&c!=EOF);
printf("Inputthevalueofaandb:");
}
return0;
}
2)gets()
char*gets(char*buffer)从stdin流中读取字符串,直⾄接受到换⾏符或EOF时停⽌,并将读取的结果存放在buffer指针所指向的字符数
组中。换⾏符不作为读取串的内容,读取的换⾏符被转换为null值,并由此来结束字符串。读⼊成功,返回与参数buffer相同的指针;读⼊
过程中遇到EOF(End-of-File)或发⽣错误,返回NULL指针。所以在遇到返回值为NULL的情况,要⽤ferror或feof函数检查是发⽣错误还
是遇到EOF。
要注意的是gets函数可以⽆限读取,不会判断上限,所以应该确保buffer的空间⾜够⼤,以便在执⾏读操作时不发⽣溢出。如果溢出,多出
来的字符将被写⼊到堆栈中,这就覆盖了堆栈原先的内容,破坏⼀个或多个不相关变量的值。