1.scanf缓存机制概念
scanf缓存机制是利用行缓存,在无\n字符出现前,输入的数据内容存入缓存,直到遇到\n,才将缓存清空进行赋值等操作。
2.实例1-连续输入
#include <stdio.h>
int main(){
int a,b,c;
scanf("%d",&a);//划重点这里的%d,而不是a=%d。下面一样
scanf("%d",&b);
scanf("%d",&c);
printf("a=%d,b=%d,c=%d\n",a,b,c);
return 0;
}
输入100 200 300 回车,当收到回车,从100开始匹配,匹配成功,赋值给a,继续往下遇到空格,忽略,匹配200赋值b。
3.实例2-匹配失败
#include <stdio.h>
int main(){
int a=0,b=0;
char str[30];
printf("b=%d\n",b);
scanf("%d",&a);
scanf("%d",&b);
scanf("%s",str);
printf("a=%d,b=%d,str=%s\n",a,b,str);
return 0;
}
输入 100 helloworld 回车
输出:
b=0
a=100,b=0,str=helloworld
当我们回车后,缓存区内有:100 helloworld,匹配发a匹配,赋值给a。helloworld匹配b,数据类型不同,匹配失败,缓存指针不动,helloworld继续匹配str,匹配成功,输出。
4.实例3-空格匹配失败
#include <stdio.h>
int main(){
int a=1,b=2;
scanf("a=%d",&a);
scanf("b=%d",&b);
printf("a=%d,b=%d\n",a,b);
return 0;
}
输入:a=99 b=88
输出:
a=99,b=2
这里b=2,因为代码中的scanf(“b=%d”,&b),缓存中匹配不会忽视空白符号,会拿空白符号去进行匹配,空格匹配b=,匹配失败。但是如果将scanf代码改成:scanf("%d",b),输入 a=99 88,就能忽视空白符号匹配成功。
所以上述代码需要匹配成功必须把空白符号除去。
输入:a=99b=88
输出:
a=99,b=88
5.scanf清空缓存
清空缓存一般用在,输入两个数据,按照习惯,一般喜欢输入完一个数据后回车再进行输入下一个数据。
#include <stdio.h>
#pragma warning(disable:4996)//在vs2019中编写程序,内存泄漏警告,忽略警告
in main(){
int a=0,b=0;
scanf("a=%d",&a);
scanf("b=%d",&b);
printf("a=%d,b=%d,a,b);
return 0;
}
这是第4点的代码,如果我们输入数据后
输入:a=100回车 //这个时候我们应该是希望下一个输入b,单数输出如下
输出:a=100,b=0
因为我们回车后直接开始读取缓存,如果在读取完a后清空缓存,再继续读取b,就能符合需求。
清空缓存的通用方式有两种:
1.getchar():读取缓存中的一个字符。
#include <stdio.h>
int main(){
int a=0,b=0;
char c;
scanf("a=%d",&a);
while((c=getchar())!='\n'&&c!=EOF);//清空缓存
scanf("b=%d",&b);
printf("a=%d,b=%d,a,b);
return 0;
}
2.正则表达式scanf("%*[^\n]"); scanf("%*c");
#include <stdio.h>
int main(){
int a=0,b=0;
scanf("a=%d",&a);
scanf("%*[^\n]"); scanf("%*c");
scanf("b=%d",&b);
printf("a=%d,b=%d,a,b);
return 0;
}
还有非通用的方式:fflush(stdin)与rewind(stdin)
fllush(stdin):不同的编译器对他的支持是不同。
rewind(stdin):本身不支持清空缓存,但是在有些编译器上有效果。
这两种方式不是在所有编译器上都能够使用。