scanf 异常分析 和 解决办法

用getchar吸掉回车等会对scanf获取数据产生干扰的字符(百试不爽)

1.scanf(“%d\n”,&t);

异常范例:

#include<stdio.h>
int main()
{
    
    
	int a[7] = {
    
    0};
	for(int i = 0;i < 5;i ++)
	{
    
    
		scanf("%d\n",&a[i]); 
	} 
	for(int i = 0;i < 7;i++)
	printf("%d :%d   ",i,a[i]); 
 } 

解决办法:
①把\n,\t等去掉就好了。如果要用\n,\t,来规范输入,可以在输入后加个printf("\n");或者printf("\t");
②如果非要用’\n’,’\t’,就在scanf后面写个getchar吸掉这些多余字符。

分析
scanf 对数据的获取是严格按照双引号内的格式进行的,所以上述例子中每输入一个数据都要有个回车,即\n来满足格式,所以输入1后的回车(\n)被当成了输入格式,而本身scanf需要一个回车(\n)来结束此次数据输入,所以再输入2时,2被留在了数据缓冲区之,直到2之后输入的回车(\n)来充当输入输入数据1的结束命令.

2.scanf(“%d”,&t);对scanf(“%c”,&c);的影响。

eg:

#include<stdio.h>
int main()
{
    
    
	char a[5] = {
    
    0};
	int k;
	scanf("%d",&k);
	for(int i = 0;i < 5;i ++)
	{
    
    
		scanf("%c",&a[i]); 
	} 
	printf("k: %d\n",k);
	printf("输出字符: "); 
	for(int i = 0;i < 5;i++)
	printf("a[%d]:%c ",i,a[i]); 
	printf("    输出字符ascii码: "); 
	for(int i = 0;i < 5;i++)
	printf("a[%d]:%d ",i,a[i]);
 }

解决方法
scanf%c使用难度较大,比较容易导致错误,所以建议谨慎使用。
①用写一个getchar在每个scanf后面吸掉回车符(个人比较建议,能过平台测试,c++也会用到)这样才能使得scanf("%c")读到想要的字符,而不是回车符。
②用scanf("%s‘’)scanf("%c")代替来获取字符(要自己先试下)
③如果只是编译器,oj上好像用不了,在scanf("%d",&k);之后加个fflush(stdin)语句可以起到清空数据缓冲区的作用。

分析:
对于这个代码样例如果自己在编译器上跑一下,结果上看,a[0]获取的是换行符,ascii码为10,'e’并没有被a获取。

用于结束scanf输入的回车被%c,当作字符获取了。建议获取字符时别用%c。%c会将空格,回车等,一切符号读入。

虽然以上问题可以通过在scanf("%d",&k);之后加个fflush(stdin)语句(清空数据缓冲去内字符。

3.使用scanf易错点。

1.注意输入数据要按照scanf内双引号给出的格式。
2.scanf中%s,不需要&,且%s不读空格,制表符,回车符,会把这些字符当做分隔符,遇到空格就停,可用gets()函数来获取含空格字符串。
3.scanf函数返回值为成功读入的数据项数。fscanf 函数返回值也是成功读入的数据项数,文件末尾隐藏着EOF,所以,最后一次会获取到EOF。

4.scanf()返回值使用

可以利用scanf和fscanf函数返回值来确定是否成功读入正确数据,具体实现如下

//method1
if(fscanf(f2,"%d %s",&s -> data.snum, s -> data.name) == 2){
    
    
	        }else{
    
    
printf("数据读取错误“);
}
//method2
while(!scanf("%d",&choose))//数据输入异常处理 
	{
    
    
		fflush(stdin);
		printf("输入错误,请输入选项(1--2):\n");
	}

猜你喜欢

转载自blog.csdn.net/RunningBeef/article/details/106205088
今日推荐