scanf的处理机制

scanf()以删除的方式从缓冲区读取数据(输入设备的数据存储缓冲区,比如键盘);也就是说,scanf从缓冲区读入一个数据项,该数据项在缓冲区中就被清除掉了。而如果scanf需要读取一个数据项,返现缓冲区当前是空的,那么程序就会在scanf代码处阻塞,等待用户输入,scanf函数接收到相应的数据项之后,在缓冲区中将这一数据项清除,scanf函数返回,程序继续执行。
格式化字符串(format string)

格式化字符串

规定了 scanf 等函数如何从输入缓冲 stdin 中读取数据,其组成字符的含义如下所示:

(1)空白字符(whitespace)。scanf 会读取并忽略在 stdin 中下一个非空白字符之前的所有空白字符(空格、换行和 tab),然后读取格式化字符串中规定格式的数据。若格式化字符串中包含空白字符,则该空白字符会与输入缓冲区中任意数量的连续空白字符相匹配,并将其从缓冲区中清除(包括0个)。例如格式化字符串"%d %d",会要求 scanf 首先从缓冲区中读取一个整型(若之前存在空白字符则跳过),再跳过输入缓冲区中连续的空白字符(与格式化字符串中的空白字符匹配),最后再读取一个整形;

(2)非空白字符(non whitespace)。对于格式化字符串中既非空白字符又不是格式说明符(format specifier,由%标识)的一部分的字符,scanf 会尝试从 stdin 中读取输入,并将输入与该字符比较,若匹配,则继续进行后续读取,若不匹配,则函数返回错误信息;

(3)格式说明符。以 % 开头的用于指定输入数据格式的字符。如 %d 指定需要读取一个整形,%s 需要读取一个字符串。scanf 等函数首先根据格式说明符尝试去解析 stdin 中的数据,如对于 %d ,scanf 会尝试对 stdin 中已有数据以整型的格式进行解析。若解析成功,则将上述解析结果存放到指定的内存中,若解析失败,如 stdin 中仅存在一个字符 ‘a’,scanf 会退出并返回,但是上述不匹配的数据并不会从缓冲区中清除,后续的 scanf 调用仍从上述输入开始读取
  除了%c 其他转化说明都会自动跳过待输入值前面所有的空格

scanf的返回值

scanf通常返回的是成功赋值(从标准输入设备赋值到参数列表所指定的内存区域)的数据项数,如果出错或是遇到end of file(注意,如果想从键盘输入EOF,在windows的DOS窗口用Ctrl+Z 或F6;在UNIX系统上,用CTRL+D。),则返回EOF

1.格式不匹配问题

#include "stdafx.h"
#include <stdio.h>
int main(int argc, char* argv[])
{int nNum = 0;scanf("%d",&nNum);//输入ABprintf("%d\n",nNum);char chA = '0';chA = getchar();printf("%c\n",chA);return 0;
}

将AB送到缓冲区,scanf函数读取缓冲区内容,发现与格式不匹配,不会把值赋给nNum,他并不会丢弃该内容,而是将其放回缓冲区,下一次缓冲区读取仍从这里开始,所以下面chA的值为A

2.scanf的返回值

#include "stdafx.h"
#include <stdio.h>int main(int argc, char* argv[])
{int nNum = 0;char chA = '0';int nResult = scanf("%d%c",&nNum,&chA);//输入ABprintf("nNum = %d\n",nNum);printf("nResult = %d\n",nResult);printf("chA = %c\n",chA);scanf("%c",&chA);printf("Again chA = %c\n",chA);return 0;
}

我们可以看到当第一个参数读取失败的时候,后面的所有都不会被读取,
当再次尝试为chA赋值的时候 缓冲区还是从指向A,从他开始读取。
而且返回值是0,表示读取成功了0个参数。

2.1

int main(int argc, char* argv[])
{int nNum = 0;char chA = '0';int nResult = scanf("%c%d",&chA,&nNum);//输入ABprintf("nNum = %d\n",nNum);printf("nResult = %d\n",nResult);printf("chA = %c\n",chA);scanf("%c",&chA);printf("Again chA = %c\n",chA);return 0;
}


我们可以看到参数的返回值是1,表示读取成功了一个参数,就是chA = ‘A’;
然后scanf尝试为参数nNum读取时,发现不匹配,将字符B放回缓冲区,并结束该次的scanf,当再次从缓冲区为chA读取数据时,读取的便是字符B了

3空白字符问题(空格 换行 和 Tab)

int main(int argc, char* argv[])
{int nNum = 0;char chA = '0';int nResult = scanf("%c%d",&chA,&nNum);//输入空格ABprintf("nNum = %d\n",nNum);printf("nResult = %d\n",nResult);printf("chA = %c\n",chA);scanf("%c",&chA);printf("Again chA = %c\n",chA);return 0;
}


chA读取的便是空格 第二次才读取到A,%c不会忽略空白字符,别的都会忽略,可以自己去尝试

scanf函数的读取相关推荐

  1. scanf函数详解与缓冲区

    1.基本信息 函数原型: int scanf( char *format, args, ...); 函数返回值: 读入并赋给args的数据个数,遇到文件结束返回EOF,出错返回0. 函数功能: sca ...

  2. scanf函数具体解释与缓冲区

    1.基本信息 函数原型: int scanf( char *format, args, ...); 函数返回值: 读入并赋给args的数据个数.遇到文件结束返回EOF,出错返回0. 函数功能: sca ...

  3. VS使用scanf函数报错解决方法

    VS使用scanf函数报错解决方法 首先来看一段很简单的C语言代码 #include<stdio.h> int main(void) {char s[10];scanf("%s& ...

  4. 【printf函数与scanf函数】(学习笔记5--标准I/O函数)

    标准I/O函数 一.printf函数 二.scanf函数 一.printf函数 printf函数通常被称为"格式化打印函数",它的第一个参数称为"格式化字符串" ...

  5. c语言程序输入与输出函数,C语言printf()和scanf()函数?其实就是输入输出

    在解释这两个函数之前,为了方便大家更容易理解,我们先来讲讲下面的这幅图. 这个图中的例子其实很简单,我们就是把题目通过输入设备(例如键盘鼠标)传输到计算机中,然后让计算机进行运算得出结果,再然后把结果 ...

  6. scanf()函数的用法

    1 scanf()函数简介 scanf()函数的作用是从标准的输入流中读取数据,并将读取到的数据保存到指定的变量中.其格式为 int scanf( const char *format [, argu ...

  7. 【C语言:精准打击】scanf_s()函数与scanf()函数的相关解决方案

    国际标准ANSI C中没有scanf_s()函数,只有scanf()函数,scanf()函数在读取时不检查边界,所以可能会造成内存泄露.故VC++2005/2008中提供了scanf_s()函数,在调 ...

  8. scanf()函数的详解以及使用时需要注意的一些细节-C语言基础

    这篇文章要探讨的是"scanf()函数的详解以及使用时需要注意的一些细节".涉及scanf()函数的应用和需要注意的问题.属于C语言基础篇(持续更新). scanf()(函数原型: ...

  9. scanf函数的用法

    1.scanf函数的原理 C语言并没有给定输入/输出关键字,其输入和输出都是通过标准函数库来实现的.C语言通过scanf 函数读取键盘输入,键盘输入又被称为标准输入.当scanf函数读取标准输入时,如 ...

  10. [C语言] scanf 函数详解多组输入法和gitee 自荐

    自荐 gitee>>> C语言学习练习: C语言学习练习 上面是我的gitee C语言仓库链接,欢迎大家来看看我写的代码.!(◦˘ ³(♡ŐωŐ♡)(给大家推荐gitee(码云)这个 ...

最新文章

  1. ActionScript 3.0 编程精髓 示例源码下载
  2. 【网络安全】SQL注入攻击思路手法总结(上)
  3. 用tomcat 发布mule 服务 (转)
  4. 每个程序员都可能犯过的10个错误
  5. spike 序列matlab,SPKtool1.0.1 神经信号spike 分类及处理 工具包 matlab 238万源代码下载- www.pudn.com...
  6. 【调用IP宏文件进行仿真】modelsim仿真时出现 Instantiation of 'xxx' failed. The design unit was not found....
  7. SpringBoot 整合Shiro实现动态权限加载更新+Session共享+单点登录
  8. 现代支付系统的资金流向
  9. TCP与UPD的比较
  10. 实现Android手机之间在局域网下传输任意文件
  11. Histromap of World History: The rise and fall of peoples and notions for 4000 years
  12. C# dataGridView控件单元格底色 dataGridView背景色 背景色调整 Header背景色前景色
  13. Eigen内存分配器aligned_allocator
  14. 如何把EXCEL文本格式里的数字批量转成文本
  15. DDR3联合HDMI进行图片数据的传输
  16. 【DDOS 防御小建议】
  17. excel就绪筛选模式_Excel自动筛选器显示筛选器模式
  18. 解决 还原SqlServer时提示文件正在使用
  19. 答题卡格子作文图片生成器
  20. winrar介绍,下载(52pojie)

热门文章

  1. 测试es from size error,from + size must be less than or equal to: [10000]异常问题
  2. 伯克利与微软联合发布Blink:使GPU计算实现高达2倍加速
  3. 施密特:下个千亿美元市值公司将出在哪个行业
  4. iphone升级ios7之后出现蓝框框一直跳的问题
  5. (转)style,currentStyle,getComputedStyle的区别和用法
  6. java学习之单件模式
  7. LeetCode 34 Search for a Range(搜索范围)
  8. MySQL 之 query cache
  9. 域用户权限|连接DC终端服务
  10. setNavigationBarTitle小程序基础性操作标题改变