scanf函数与输入缓冲区
本文链接:http://www.cnblogs.com/xxNote/p/4008668.html
今天看书的时候遇到scanf函数与缓冲区的问题,产生了一些猜想即:应该有一个指针来记录缓冲区中读取到了哪个字符。书上说scanf函数在%d、%f、%lf等数值控制字符时会跳过缓冲区中的空格、回车、还有制表符(TAB),若遇到+*等字符则会失败而不再跳过;而scanf函数在%c或%s控制字符时则会取走缓冲区的所有字符。此时产生一个疑问,这里的跳过说的是直接改变前面猜想中的那个指针的值还是仅仅跳过而不改变指针的值下一次读取还从指针指向的位置读取呢?
就写了下面的小程序,用这两个输入测试了一下,程序如下:
#include <stdio.h> int main(void)
{
int ch[5];
//第一次输入:
// 1++2*3
//第二次输入:
// 1【空格】【空格】2【空格】3
//两次输入将会得到不同的结果,这是因为scanf函数在%d、%f、%lf等数
//值控制字符时会跳过缓冲区中的空格、回车、还有制表符(TAB)
//而scanf函数在%c或%s控制字符时则会取走缓冲区的所有字符,
//由此猜也可以猜想到应该有一个指针来记录缓冲区中读取到了哪个字符 scanf("%d", &ch[0]);
scanf("%d", &ch[1]);
ch[2] = getchar();
ch[3] = getchar();
printf("ch[0]:%0x\n", ch[0]);
printf("ch[1]:%0x\n", ch[1]);
printf("ch[2]:%c\n", ch[2]);
printf("ch[3]:%c\n", ch[3]);
printf("%d ch[4]:%d\n", scanf("%d", &ch[4]), ch[4]);
printf("%d\n", ch[4]);
//当输入是“1【空格】【空格】2【空格】3”的时候,
//由23行和24行的输出结果的差异反映了一个事实即:
//__cdecl调用约定是从右到左将参数依次压入栈中
//23行程序传递ch[4]的时候,ch[4]还没有初始化,而
//本程序是在Debug模式下编译运行的所以打印出的值是:cccccccc
//在10进制下这个数值是-858993460(以后见到这个数值的时候检查一下是否忘记初始化)
//23行执行后ch[4]被赋值为我们输入的值,所以24行输出了我们预料中的值
return 0;
}
两种输入的运行结果分别如下:
1++2*3的运行结果:

1【空格】【空格】2【空格】3的运行结果:

后面的这个输出结果比较有意思,也就是23行和24行的ch[4]的值的输出结果的差异是由于__cdecl调用约定是从右到左将参数依次压入栈中。
scanf函数与输入缓冲区的更多相关文章
- scanf()中清除输入缓冲区的几种方法归纳
应用场景:我们使用多个scanf()的时候,如果输入缓冲区还有数据的话,那么scanf()就不会询问用户输入,而是直接就将输入缓冲区的内容拿出来用了,这就导致了前面的错误影响到后面的内容,为了隔离这种 ...
- [转][修]C清空输入缓冲区
为何要清空输入缓存区 读取时输入缓冲区中的内容会被scanf函数逐个取走,正常case下scanf()函数可以根据返回值判断成功取走的数目:但当发生读取异常之后,输入缓冲区中的内容并未被取走, ...
- C 清空输入缓冲区,以及fflush(stdin)的使用误区和解决方法
转载:https://blog.csdn.net/Veniversum/article/details/62048870 对C 语言初学者来说,fflush(stdin)函数被解释为会清空输入缓冲区的 ...
- scanf函数读取缓冲区数据的问题
标准I\O的缓冲类型 标准I\O根据不同的应用需求,提供了全缓冲.行缓冲.无缓冲三种缓冲方式. 全缓冲:只有当划定的缓冲区被填满或者数据读取至末尾时,才开始执行I\O操作(执行系统提供的read\wr ...
- C语言scanf函数详细解释
原文链接 函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化输入函数,它从标准 ...
- C语言scanf函数详解
函数名: scanf 功 能: 运行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化输入函数,它从标准输入设 ...
- c语言scanf()停止接受输入及scanf("%c",&c)吃掉回车或者空格字符的问题
scanf()函数接收输入数据时,遇以下情况结束一个数据的输入:(不是结束该scanf函数,scanf函数仅在每一个数据域均有数据,并按回车后结束). ① 遇空格."回车& ...
- scanf()函数
Scanf函数攻略: (A) 格式化说明符 格式字符 说明 %d 读入十进制整数 %u ...
- scanf函数详解
函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]);scanf()函数是通用终端格式化输入函数,它从标准输入设备(键 ...
随机推荐
- Vector & ArrayList 的主要区别
1) 同步性:Vector是线程安全的,也就是说是同步的 ,而ArrayList 是线程序不安全的,不是同步的 数2. 2)数据增长:当需要增长时,Vector默认增长为原来一倍 ,而ArrayLis ...
- mybatis 传递参数的方法总结
有三种mybatis传递参数的方式: 第一种 mybatis传入参数是有序号的,可以直接用序号取得参数 User selectUser(String name,String area); 可以在xml ...
- [转发]黑苹果修改DSDT彻底解决关机不断电和睡眠问题
1. 在 Method (_PTS, 1, NotSerialized)之前添加一个OperationRegion (PMRS, SystemIO, 0x0430, 0×13),如下: Operati ...
- HBase filter shell操作
创建表 create 'test1', 'lf', 'sf' lf: column family of LONG values (binary value) -- sf: column family ...
- SpringMVC处理请求流程
SpringMVC核心处理流程: 1.DispatcherServlet前端控制器接收发过来的请求,交给HandlerMapping处理器映射器 2.HandlerMapping处理器映射器,根据请求 ...
- python的简洁是shell无法代替的
之前线上服务器分发配置都是用shell和expect脚本分发,脚本写了很长,上周换了ansible,现在自己用python写一个,就30行代码就可以实现需求,之前的shell写了快200行了,蛋疼,代 ...
- thinkphp 3.2响应头 x-powered-by 修改
起初是看到千图网的登录链接 查看到的 自己做的网站也看了下 修改的办法就是TP3.2.2 的框架里 具体路径是D:\www\ThinkPHP\Library\Think\View.class.php ...
- SQL查询表字段的信息
如题,代码: select * from information_schema.columns where table_name = 'TableName'
- JQuery Easy Ui 可装载组合框 - ComboBox
可装载组合框 - ComboBox 继承自$.fn.combo.defaults,通过$.fn.combobox.defaults覆盖默认值 combobox显示的是一个可以编辑的文本框和一个下拉列表 ...
- php正则表达式匹配用户名规则:由字母开头的6-16位字母和数字组成的字符串
$pattern = '/^[a-zA-Z]{1}[a-zA-Z0-9]{5,15}$/i';