C++scanf_s()函数的⽤法以及注意事项
前⾝——scanf()
有的教材⾥⽤的scanf(),其实在⽬前Visual Studio版本中已经弃⽤了,⽤scanf_s()函数代替了。
为什么现在要⽤scanf_s()
scanf_s()函数是Microsoft公司VS开发⼯具提供的⼀个功能相同的安全标准输⼊函数,从vc++2005开始,VS系统提供了scanf_s()。在调⽤该函数时,必须提供⼀个数字以表明最多读取多少位字符。另外,很多带“_s”后缀的函数是为了让原版函数更安全,传⼊⼀个和参数有关的⼤⼩值,避免引⽤到不存在的元素,防⽌hacker利⽤原版的不安全性(漏洞)⿊掉系统。简单的理解,就是scanf_s会⽐scanf更安全,那么为了安全也需要编程者多传⼀些参数,这些参数就是变量的长度(占⽤的字节数)。
很多带“_s”后缀的函数是为了让原版函数更安全,传⼊⼀个和参数有关的⼤⼩值,避免引⽤到不存在的元素,有时⿊客可以利⽤原版的不安全性⿊掉系统。⽐如:char d[20];写成scanf_s("%s",d,20);才是正确的,有这个参数20使准确性提⾼。
注意事项
下列代码
double a,b,c;
scanf_s("%f%f%f",&a,&b,&c);
printf("%f%f%f",a,b,c);
打印结果:
512181,17989019,86000000
可以看到为3个随机数
为啥会这样呢?
scanf_s读%f时,系统会按照4字节长度来读,读完要放到⼀个4字节的空间位置,也就是⼀个float所在的位置。那么double有8字节空间,⽐4字节还⼤,能不能来放?答案是不能。因为float和double的关系不像int和long的关系那样,简单的在后⾯增加4字节的位置。float和double有⾃⼰专门的数据排列格式,如下:如果读的时候明明是按照float的格式来读,但是却存在double的空间内,并且之后⼀直按double来操作,那么⾥⾯数据的符号位、阶码、尾数就全错位了。除⾮你在⽤的时候把每个double强制转换成float来⽤,但是何必多次⼀举?同理,如果读⽤%lf来读,却存在float中,不仅格式错位,⽽且存储空间
也不够,会有数据丢失。所以⽤scanf_s读的时候,读%f就规规矩矩的放进float中来存,读%lf就放进double中,这样在使⽤的时候⾥⾯的数据才不会错位。在printf的时候,⾸先C++⾥⾯的float其实在使⽤过程中都是被隐式转换成了double来⽤。所以你在printf时⽤float还是double其实是⼀样的。⽤%f和%lf都可以。
所以正确的写法是
编程scanf是什么意思double a,b,c;
scanf_s("%lf%lf%lf",&a,&b,&c);
总结
(1)printf的%f说明符既可以输出float型⼜可以输出double型。
根据“默认参数提升”规则(在printf这样的函数的可变参数列表中,不论作⽤域内有没有原型,都适⽤这⼀规则)float型会被提升为double型。因此printf()只会看到双精度数。(2)scanf对于float类型必须⽤%f,double必须⽤%lf
对于scanf,情况就完全不同了,它接受指针,这⾥没有类似的类型提升。(通过指针)向float存储和向double存储⼤不⼀样,因此,scanf区别%f和%lf。
(3)事实上,printf中没有定义%lf,但是很多系统可能会接受它。要确保可移植性,就要坚持使⽤%f。
要想保留⼩数位数,请使⽤(⽐如保留8位⼩数):
printf("%.8f",a);

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。