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. Java并发编程—Synchronized底层优化(偏向锁、轻量级锁)
  2. Filter_细节_执行流程生命周期
  3. 29岁当教授,发表11篇Nature和Science,这位顶尖科学家正式全职回国
  4. Linux 如何隔离CPU核心 isolcpus=0-2
  5. Python 基础知识 D5
  6. python使用-python使用
  7. bzoj 3110: [Zjoi2013]K大数查询(树套树)
  8. 2018 CCPC 桂林站(upc复现赛)总结
  9. 洛谷P2678 跳石头
  10. 主子式大于等于零的矩阵是半正定矩阵的证明方法之二
  11. 隔壁小孩也能看懂的面向对象(概念篇)
  12. 2022年道路运输企业安全生产管理人员考题及答案
  13. 浅谈IPv6网络安全问题及解决对策
  14. 智能窗帘传感器c语言程序,单片机智能家居电路控制程序+Proteus仿真+视频(光烟雾传感器与自动窗帘)...
  15. java并发三大特性--有序性、可见性、原子性
  16. orcale 基本語法
  17. 定时任务:创建静态定时任务、动态定时任务
  18. 数字化经济带领各行各业迎来碧海蓝天
  19. 研究人员创建一种安全的CAR T细胞疗法来对抗儿童的实体瘤
  20. C++ ifstream eof()的使用

热门文章

  1. apollo重要服务之metaService
  2. ThreadLocal是什么?ThreadLocal的原理分析
  3. 线程的属性和 线程特定数据 Thread-specific Data
  4. 兼具颜值与智慧 华为Mate 10 Pro体验图赏
  5. select2中的ajax请求
  6. BASH 进阶(转载防丢)
  7. 苹果开发者中心宕机8天终于回归
  8. 如何让你的网站快速被百度收录。
  9. Linux cache清理
  10. windbg使用教程: 具体实例