scanf
接收用户的输入,没有任何隐式的转换,必须使用对应的转换说明来接收需要的值。例如接收字符必须使用%c
以%c的方式接收输入,如果输入的是数字的数值,scanf并不会认为是字符,直接将其略过,寻找合适的转换说明来接收。
scanf函数比较危险:转换说明必须一一对应
函数参数会从栈当中指定的位置一格一格的读取,在printf当中,如果当前传进去的参数是%d,printf就会根据传递的参数用%d依次读取第一个,第二个,并不会对数据进行判断,转换。所以经常会得到错误的值。
scanf 会要求用户进行输入,而scanf只规定了从哪儿开始读取,并没有指定读取到哪儿,在这其中就可能读取到一些恶意的代码(缓存区溢出)
scanf_s 只会允许写入读取规定大小的区域,不会允许读取,运行其他区域。
scanf_s
int main()
{
int i_num = 0 ; i_othernum = 0;
double d_num = 0.0 ;
char c_character = 0;
char str_demo[40] = { 0 }, str_other[40] = { 0 };
//输入a12344
scanf_s("%d",&i_num); 没有读取到任何值 ,第一个待读取的区域不是待写入的值,放弃写入
scanf_s("%d",&i_num); 同上,没有读取到任何值,说明程序没有发生阻塞,数据存在输入缓存区中,只要有东西,scanf_s就会从缓冲 区读取
scanf_s("%c",&c_character); 读取出 a 然后放弃写入
scanf_s("%d",&i_num); 发现缓存区中还有数据,符合%d 于是 读取出12344 缓存区为空,发生阻塞,等待输入。
// 输入I Love Mark ! SoSo
scanf_s("%s",str_demo,sizeof(str_demo)); 读取 I %s按照空格来区分,当读取到一个空格时,会把之前的字符读取到变量中
scanf_s("%s",str_demo,sizeof(str_demo)); 读取 Love
scanf_s("%s",str_demo,sizeof(str_demo)); 读取 Mark!
scanf_s("%s",str_demo,sizeof(str_demo)); 读取 SoSo 缓存区为空 ,发生阻塞
// 输入 a12344
scanf_s("%s",str_other,sizeof(str_demo)); 全部读取出来 ,因为没有空格
// 输入 10 10
scanf_s("%d %d",&i_num,&i_othernum); 两边的值读取出来
//输入 20,30(全角逗号)
scanf_s("%d %d",&i_num,&i_othernum); 只读取出20 ,格式不符合(空格%d),在缓冲区中找不到合适的格式
scanf_s("%d,%d",&i_num,&i_othernum); 不会被读取
scanf_s("%d ,%d",&i_num,&i_othernum); %d不符合,直接跳转下一句
scanf_s(",%d",&i_num,);
scanf_s(",%d",&i_othernum); 符合要求,读取出数据
必须拿着相同的类型相同的格式,才能按照我们的想法输入到指定的地方
//输入4050
scanf_s("%d%d",&i_num,&i_othernum); 把4050看成一个数,在等待输入下一个数
//输入 60 回车 70
scanf_s("%d%d",&i_num,&i_othernum); 正确读取到数值
}