前身——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都可以。

所以正确的写法是

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);

C++ scanf_s()函数的用法以及注意事项的更多相关文章

  1. Oracle的trim( )、ltrim( )、rtrim( )三个函数的用法及注意事项

    学习一下用法整理trim().ltrim().rtrim()的用法 trim().ltrim().rtrim()三个函数有两个作用,分别是: 一.去除字符串前后空格(基本用法) trim(string ...

  2. memset函数用法及注意事项

    头文件 #include<cstring>// or #include<memory.h> ------------------------------------------ ...

  3. PHP中header函数的用法及其注意重点是什么呢

    1.使用header函数进行跳转页面: header('Location:'.$url); 其中$url就是将要跳转的url了. 这种用法的注意事项有以下几点: •Location和":&q ...

  4. C语言中关于scanf函数的用法

    scanf()函数的控制串 函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化 ...

  5. MYSQL中str_to_date函数的用法

    str_to_date(str,format) 函数的用法 str_to_date函数将str转化为日期型的数据,format表示转化后的格式. format参数格式: 常用: %Y  年 %m  月 ...

  6. Python内置函数reversed()用法分析

    Python内置函数reversed()用法分析 这篇文章主要介绍了Python内置函数reversed()用法,结合实例形式分析了reversed()函数的功能及针对序列元素相关操作技巧与使用注意事 ...

  7. 有关日期的函数操作用法总结,to_date(),trunc(),add_months();

    相关知识链接: Oracle trunc()函数的用法 oracle add_months函数 Oracle日期格式转换,tochar(),todate() №2:取得当前日期是一个星期中的第几天,注 ...

  8. Oracle to_date()函数的用法

    Oracle to_date()函数的用法 to_date()是Oracle数据库函数的代表函数之一,下文对Oracle to_date()函数的几种用法作了详细的介绍说明,供您参考学习. 在Orac ...

  9. js中bind、call、apply函数的用法

    最近一直在用 js 写游戏服务器,我也接触 js 时间不长,大学的时候用 js 做过一个 H3C 的 web的项目,然后在腾讯实习的时候用 js 写过一些奇怪的程序,自己也用 js 写过几个的网站.但 ...

随机推荐

  1. 实践解析丨Rust 内置 trait:PartialEq 和 Eq

    摘要:Rust 在很多地方使用了 traits, 从非常浅显的操作符重载, 到 Send, Sync 这种非常微妙的特性. Rust 在很多地方使用了 traits, 从非常浅显的操作符重载, 到 S ...

  2. 复制粘贴Ctrl+C改为自定义单键

    目录 那一瞬间不想用Ctrl+C了 (一)搜索渠道 关键词搜索 (二)方案对比 (三)最终方案Ditto 使用方法 (四)案例 1. 替换Ctrl+C快捷键: 2. 将英文小写替换为大写: 那一瞬间不 ...

  3. 「HTML+CSS」--自定义加载动画【008】

    前言 Hello!小伙伴! 首先非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 哈哈 自我介绍一下 昵称:海轰 标签:程序猿一只|C++选手|学生 简介:因C语言结识编程,随后转入计算机 ...

  4. 问题笔记-vueCli3.0打包路径出错

    需求:vueCli3.0打包路径出错.解决办法:vueCli3.0打包,新版本更新脚手架做出精简,webpack配置文件需要手动配置.在文件根目录创建一个vue.config.js配置文件.基本版: ...

  5. Kafka 消息存储机制

    Kafka 消息以 Partition 作为存储单元,那么在 Partition 内消息是以什么样的格式存储的呢,如何处理 Partition 中的消息,又有哪些安全策略来保证消息不会丢失呢,这一篇我 ...

  6. java面试一日一题:如何优化sql

    问题:请讲下在mysql下如何优化sql 分析:该问题主要考察对mysql的优化,重点考虑对索引优化的掌握. 回答要点: 主要从以下几点去考虑, 1.什么样的sql需要优化? 2.怎么对sql进行优化 ...

  7. .netcore ioc 循环依赖问题及其相关思考之DispatchProxy

    .netcore引入了ioc机制让开发人员逐步习惯从过去的各种new对象变成通过IOC框架来管理对象的生命周期.这样当我们需要某个对象的时候,我们一般在构造函数里申明该对象的接口,即可通过ioc容器创 ...

  8. 由奶茶店突发奇想开始了Java设计模式:享元模式

    目录 定义 意图 主要解决问题 何时使用 优缺点 结构 奶茶摊位的例子 奶茶店的例子 在什么情况下使用享元模式 定义 享元模式是对象的结构模式,享元模式以共享的方式高效的支持大量的细粒度对象,主要用于 ...

  9. 面试题:让你捉摸不透的 Go reslice

    面试题: package main func a() []int { a1 := []int{3} a2 := a1[1:] return a2 } func main() { a() } 看到这个题 ...

  10. C++ 内存模型之单独编译

    单独编译得意义 将一个程序分成多个文件按保存,如果过对程序修改,找到要修改得文件进行修改后重新编译,则可以之重新编译该文件,然后后将他于其他文件得编译版本链接,是的大程序得管理更加高效便捷. 将单文件 ...