本文链接: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函数与输入缓冲区的更多相关文章

  1. scanf()中清除输入缓冲区的几种方法归纳

    应用场景:我们使用多个scanf()的时候,如果输入缓冲区还有数据的话,那么scanf()就不会询问用户输入,而是直接就将输入缓冲区的内容拿出来用了,这就导致了前面的错误影响到后面的内容,为了隔离这种 ...

  2. [转][修]C清空输入缓冲区

    为何要清空输入缓存区     读取时输入缓冲区中的内容会被scanf函数逐个取走,正常case下scanf()函数可以根据返回值判断成功取走的数目:但当发生读取异常之后,输入缓冲区中的内容并未被取走, ...

  3. C 清空输入缓冲区,以及fflush(stdin)的使用误区和解决方法

    转载:https://blog.csdn.net/Veniversum/article/details/62048870 对C 语言初学者来说,fflush(stdin)函数被解释为会清空输入缓冲区的 ...

  4. scanf函数读取缓冲区数据的问题

    标准I\O的缓冲类型 标准I\O根据不同的应用需求,提供了全缓冲.行缓冲.无缓冲三种缓冲方式. 全缓冲:只有当划定的缓冲区被填满或者数据读取至末尾时,才开始执行I\O操作(执行系统提供的read\wr ...

  5. C语言scanf函数详细解释

    原文链接 函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化输入函数,它从标准 ...

  6. C语言scanf函数详解

    函数名: scanf  功 能: 运行格式化输入  用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化输入函数,它从标准输入设 ...

  7. c语言scanf()停止接受输入及scanf("%c",&c)吃掉回车或者空格字符的问题

    scanf()函数接收输入数据时,遇以下情况结束一个数据的输入:(不是结束该scanf函数,scanf函数仅在每一个数据域均有数据,并按回车后结束).          ① 遇空格."回车& ...

  8. scanf()函数

    Scanf函数攻略: (A)                格式化说明符 格式字符           说明 %d                 读入十进制整数 %u                 ...

  9. scanf函数详解

    函数名: scanf 功 能: 执行格式化输入 用 法: int scanf(char *format[,argument,...]);scanf()函数是通用终端格式化输入函数,它从标准输入设备(键 ...

随机推荐

  1. python 读取 redis -安装redis-py

    先下载  https://github.com/andymccurdy/redis-py 到本地 然后打开 Cmd.exe 进入当前目录 后执行 执行成功后,在python里检测 没有任何错误提示 就 ...

  2. SQLServer------解决IP地址登录不了数据库问题

    1.找到配置管理器,打开 2.关掉SQLExpress,打开MSSQLServer 3.配置MSSQLServer(启用Named Pipes和TCP/IP) 4.修改TCP/IP属性(端口:1433 ...

  3. 如何修改Linux主机名

    Linux 下什么都比较麻烦,就连修改主机名也不例外.我们就下文说一下具体方法. Linux 安装好后,其默认的主机名是 localhost.修改 Linux 主机名需要3步. 使用 hostname ...

  4. datagrid---写后台数据交互

    1.action的写法: 开头写包,此外,我们还有一个和action并列的package-info.java的文件,该文件是包的信息,media为我的文件夹里面放三个文件夹(action,bpo,ma ...

  5. ubuntu rhythmbox乱码解决方法

    因为安装的是双系统,所以音乐文件在win的盘下面,所以采用的方法是 1. 首先,需要有软件包mid3iconv.如果你的系统中没有安装它,可以通过如下代码自动安装:sudo apt-get insta ...

  6. Linux 命令小记

    1. pidof 进程名 :获取进程的pid,例如 pidof memcached 得到5333 2. unset Shell变量 :取消设置一个shell变量,从内存和shell的导出环境中删除它, ...

  7. POJ 2389 Bull Math(水~Java -大数相乘)

    题目链接:http://poj.org/problem?id=2389 题目大意: 大数相乘. 解题思路: java BigInteger类解决 o.0 AC Code: import java.ma ...

  8. C#----GDI+画图的一些注意和细节

    画线: 在矩形rect(0,0,20,20)中的位置Point(0,10),Point(20,10)画线,也就是在矩形的中间画线,线的宽度是20的话,会发现正好线会把矩形占满,说明画线不是向下或者向上 ...

  9. WebApp基础01-设置读取assets目录下文件

    要读取assets下的目录,只需要修改三个地方即可 1.res/layout/activity_main.xml 2.AndroidManifest.xml 3.src\com\example\lcy ...

  10. PHP与Javascript的混合测试

    js调用php <?php $num=88; ?> <script> var a = <?php echo $num;?>; alert(a); </scri ...