printf和scanf整理(后续填补)
scanf和printf头文件:<stdio.h>
1.%d、%3d、%03d、%-3d区分
%d:以十进制形式输出整数(int)
%3d:指定宽度为3,不足的左边补空格
%03d:一种左边补0 的等宽格式,比如数字12,%03d出来就是: 012
%-3d:左对齐,不足三位右边用空格填补
#include<stdio.h>
int main()
{ int a = , b = , c = ;
printf("%d %d %d\n", a, b, c);
printf("%3d\n%3d\n%3d\n", a, b, c);
printf("%03d\n%03d\n%03d\n", a, b, c);
printf("%-3d\n%-3d\n%-3d\n", a, b, c);
return ;
}
2.scanf和scanf_s的区别
①一般情况下,两者可互相代替:有个int型变量a,于是有scanf("%d",&a)等价于scanf_s("%d",&a)
②scanf_s并非是标准库的函数,而是VS中用以确保数据不会溢出。
比如,有个char b[10]的字符数组,一般下用scanf("%s",b),但是如果输入时的字符串长度超过9呢?(大小为10的字符数组最多存储长度为9的字符串,因为最后一个位置要存储空字符)可能会导致溢出或对程序之后的输入造成影响。

(图 dev-C++编译)
可见,scanf可能会造成内存泄漏,尽管可能上图这种情况下能正确执行(和编译器对代码检查严格是否有关),但是的的确确会有逻辑错误(数组b的元素最大下标是9,而这里b[10]竟然能够成立),而这对于程序员而言是不允许的。
如果换成在VS 2015 IDE中编译(上面这个程序不在VS中执行,是因为scanf函数在VS中会报错,除非对编译环境进行修改(本萌并没有试过~)),采用scanf_s函数如下:
#include<stdio.h>
int main()
{
char b[] = { '\0' };
scanf_s("%s", b,);
int n;
scanf_s("%d",&n);
printf("b=%s\nn=%d\n", b, n);
printf("b[9]=%c\n", b[]);
return ;
}
执行情况:

图1:由于输入的字符串长度超过9,并且大于10,以至于读入b数组出错,经过调试会发现,此时b中第一个为ASCII码为0的空字符,之后9个竟然是ASCII值为-2的'?'。b数组输入结束后,由于输入流此时还有数据,缓冲不为空,以至于给整型n赋值时直接从输入流中读取剩下的数字(注意,此时存入n为数字,而不是字符)。
图2:当刚好输入10个字符时,由于b数组只能存长度为9的字符串,仍然出错。但是此时输入流缓冲为空,所以能继续输入数据,赋值给b。
图3:当输入的字符串长度小于等于9时,则是正常输入情形。由于b[9]为空字符,而空字符并不能显示输出,就有图3的结果。
③scanf_s用法:当不是输入字符串时,和scanf格式相同;当输入字符串时,必须要在最后指出最大读入的字符个数(注意,不是字符串长度,读者可以尝试将上个代码中的10改为9,然后采用图3的输入数据,b数组则会出错)。
printf和scanf整理(后续填补)的更多相关文章
- printf和scanf
一 printf和scanf(printf和scanf是c语言中的输入输出库函数) printf(”格式控制“,输出列表) <1>格式控制 其中包含 格式声明(%+相应格式对应字母).转义 ...
- C的printf与scanf的用法
之前没学过C语言,只学过C++,所以就来自学下C语言了,其实个人认为C与C++的区别很小,基本上就是printf与scanf这点输出和输入的区别了,如果还有什么区别的话那就是要包含的头文件是不同的.比 ...
- 【转】stm32CubeMx上移植自己的printf()和scanf()函数
要想printf()和scanf() 函数工作,我们需要把printf()和scanf() 重新定向到串口中.重定向是指用户可以自己重写C 的库函数,当连接器检查到用户编写了与C 库函数相同名字的函数 ...
- printf()与 scanf()
一直以来就没有认真看过控制台输入输出的格式,现今找了一些材料,分享如下: 1. 格式化规定符 Turbo C2.0提供的格式化规定符如下: ━━━━━━━━━━━━━━━━━━━━━━━━━━ ...
- C语言: 运算符,printf,scanf的用法
运算符/的运算结果和运算对象的数据类型有关,两个数都是in,则商就是int,取整数部分:被除数和除数中只要有一个或两个都是浮点型数据,则商也是浮点型,不去掉小数部分如:16/5 == 3:16/5.0 ...
- 数据类型、常量、变量、printf、scanf和运算符
数据类型 常量 变量 printf函数介绍 scanf函数介绍 运算符 数据类型 数据类型是指数据在内存中存储的方式. C语言中有5大数据类型:基本类型.构造类型.指针类型.空类型.定义类型. C语言 ...
- 重学C语言 -- printf,scanf
printf(); 用来显示格式串的内容 注意: 参数不可以换行,否则会出一个警告. 格式串中占位符比表达式数量多 会显示一个无意义值 格式串中占位符比表 ...
- printf与scanf的返回值、注意点
printf()的返回值为其输出字符串常量的字符数(注意字符数与字数的区别)注意计数针对所有的打印字符,包括空格和不可见的换行字符(不包括字符串的空字符). scanf()函数返回成功读入的项目的个数 ...
- C++中printf和scanf的用法
(一)printf的用法 printf:按格式打印,向控制台输出.print:打印 ,f:formate,格式化. 在使用printf向控制台输出时,不建议使用中文字符串,中文字符串的问题比较复杂,有 ...
随机推荐
- 【运维工程师必知必会】——MySql基础
一.SQL语句 1.分类 DDL(data definition language)数据定义语言(create.alter.drop),管理基础数据.例如:库.表 #运维要熟练,开发也要熟练 ...
- 整合最优雅SSM框架:SpringMVC + Spring + MyBatis
我们看招聘信息的时候,经常会看到这一点,需要具备SSH框架的技能:而且在大部分教学课堂中,也会把SSH作为最核心的教学内容. 但是,我们在实际应用中发现,SpringMVC可以完全替代Struts,配 ...
- 从零开始构建一个的asp.net Core 项目(二)
接着上一篇博客继续进行.上一篇博客只是显示了简单的MVC视图页,这篇博客接着进行,连接上数据库,进行简单的CRUD. 首先我在Controllers文件夹点击右键,添加->控制器 弹出的对话框中 ...
- [刷题]算法竞赛入门经典(第2版) 6-7/UVa804 - Petri Net Simulation
题意:模拟Petri网的执行.虽然没听说过Petri网,但是题目描述的很清晰. 代码:(Accepted,0.210s) //UVa804 - Petri Net Simulation //Accep ...
- MyBatis之简单了解Plugin
MyBatis的Configuration配置中有一个Plugin配置,根据其名可以解释为"插件",这个插件实质可以理解为"拦截器"."拦截器&quo ...
- js事件小结
首先事件绑定分为2种方法 一种为"DOM0级"方法,这里我理解为事件指定 var oDiv = document.getElementById("div1"); ...
- 局域网内部署 Docker Registry
在局域网内部署 Docker Registry 可以极大的提升平时 pull.push 镜像的速度,从而缩短自动化操作的过程.同时也可以缓解带宽不足的问题,真是一举多得.本文将从创建单机的 Docke ...
- 《Android进阶》之第六篇 Fragment 的使用2
最近通过学习,对fragment的使用有了新的认识. 一开始接触android的时候,很是受不了这个fragment,总感觉它把一个简单的事情搞复杂啦,所以每次新建工程的时候总是固执的选择empty ...
- 解决Cornerstone不能上传.a文件的问题 Cornerstone不上传*.xcuserstate,*.xcbkptlist文件
在使用CornerStone的时候经常会出现.a文件无法上传的问题,导致从svn checkout到本地的时候编译报错 这里可以通过配置CornerStone来达到上传.a文件的效果 操作步骤: 打开 ...
- 【试验局】ReentrantLock中非公平锁与公平锁的性能测试
硬件环境: CPU:AMD Phenom(tm) II X4 955 Processor Memory:8G SSD(128G):/ HDD(1T):/home/ 软件环境: OS:Ubuntu14. ...