看了一下glibc scanf的源码之后,对scanf的使用方法有了更深入的理解,下面给大家讲解一下scanf函数的用法.

1.以%开头的字符串

%[argpos$] [I'*] [maximum field width] [type modifiers] [arg]
  1. argpos: 指定了参数的位置
  2. I’*
    • I:use locale’s digits
    • ': Group numbers
    • *: 跳过这个参数
  3. maximum field width : 从输入的内容中最多读取几个字符
  4. type modifiers:
    - hh 写 一个字节
    - h 写两个字节
    - 写四个字节
    - l 写八个字节
    - ll 写八个字节
    - m 有scanf分配缓冲区
  5. arg
    - % 输出%
    - n将前面已经读取的字符个数写到参数指定的位置
    - c 字符
    - C wchar_t
    - s 字符串
    - S wchar_t字符串
    - p 地址
    - x/X 十六进制字符串
    - u/d 无符号/有符号整数
    - e/E/f/F 浮点数
    - [] []内字符以外的字符作为定界符
    - [^] [] 内的字符作为定界符

2.非%开头的字符串

读取一个字符,与之相比较,不同的话scanf失败。

3.演示

3.1 例1

char*p = NULL;
int n = 0;
scanf("Hello%2$10ms%3$n",0,&p,&n);

解析流程:

  1. scanf会从格式串的第一个字符开始遍历,若字符不是%,那么与读入的字符相比较,相同的话,遍历下一个字符。
  2. 当scanf遇到%的时候,之后读取到了2,读取到$后,scanf会把数据保存在第二个参数
  3. 继续解析10 ,这个10的含义就是,从输入的内容中最多读取10个字符。
  4. 解析到m,scanf会自己创建一个缓冲区,把从输入的内容中转换的结果写到这个缓冲区内,最后把缓冲区地址写到参数指定的位置
  5. 解析到s,scanf之后将会读取字符串到指定的buffer内.
  6. 后面的%3 $n同理,scanf会把前面已经读取的字符数写到第三个参数指定的地址处。

接着我们输入 HelloAAAAAAAAAAAA
Hello与格式串中开始位置的Hello相匹配,继续看后面
%2$10ms,最多读取10个字符,并且自己创建缓冲区,把字符串,也就是10个A读到自己创建的缓冲区内,并把地址写到第二个参数指定的位置。
%3 $n ,前面读取了15个字符,所以这里会把15写到第三个参数指定的位置
运行看一下:

再输入内容 Helaaaaaa看一下,匹配成功三个字符,然后第四个失败,scanf结束,最后p 任然是0,n任然为0

3.2 例二

int val = 0;
scanf("Haha%2$10hhd",0,&val);

解析流程:

  1. 匹配Haha
  2. 2$将转换后的结果写到第二个参数指定的位置
  3. 10从输入内容中最多读取10个字符
  4. 只写1个字节

接下来输入内容Haha000000000000000123,由于匹配Haha之后最多读取10个字符,所以最后得到的整数是0。

接着我把这里val的初始值改一下,改为0xabcd,然后输入同样的内容。

最后的val并不是0,为什么呢???
原因是我们这里指定了只写一个字节.所以最后val的值是0xab00,只有低字节发生了变化。

3.3例三

char buffer[256] = {0};
int n = 0;
scanf("Hello%2$10[^abc]%1$n",&n,buffer);

解析流程:

  1. 匹配Hello
  2. 2$将转换结果写到第二个参数指定的位置
  3. 10最多读取10个字符
  4. [^abc],abc这三个字符中的任意一个都是定界符
  5. %1 $n将前面读取的字符个数写到第一个参数指定的位置

接下来输入内容: Hellohhhhhhhhhhhh,匹配Hello之后,最多读取10个字符到第二个参数里面,所以最后buffer里面有10个h,%1 $n,解析到这里时,前面读取了15 个字符,所以会把15写到n里面。

接下来输入 Hellohhhhhh,然后按下回车,我们会发现,什么也没输出。

为什么呢???因为我们指定了定界符为abc,此时的换行符已经不是定界符了,换行符也被读到了buffer里面。
我们继续输入gga,然后回车。scanf会把gg读到buffer里面,然后遇到a,结束。一共读取了 5(Hello) + 6 (hhhhhh) + 1 (\n) + 2(gg) = 14个字符

并且我们可以发现,hhhhhh和gg中间是有一个换行符的,说明换行符确实被读进去了。

End

上面这些用法是我在阅读scanf的源码时发现的,(glibc-2.23),msvc上可能有一部分功能是无法使用的,或者某些功能并不是标准里面含有的。有一部分这里没有介绍到,感兴趣的话大家自己实验吧(有些没用过,代码太多,最后懒得看了,毕竟主要是为了找到哪里调用了malloc来触发malloc_hook)

c语言scanf用法详解相关推荐

  1. c语言struct的作用和用法,c语言struct用法详解

    c语言struct用法详解 在C语言中,可以使用结构体(Struct)来存放一组不同类型的数据.结构体的定义形式为:struct 结构体名{ 结构体所包含的变量或数组 }; 结构体是一种集合,它里面包 ...

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

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

  3. sscanf c语言程序,C语言 sscanf用法详解

    /*sscanf用法详解*/#include /*sscanf头文件*/#include#include /*sscanf 读取格式化的字符串中的数据. swscanf 是 sscanf 的宽字符版本 ...

  4. C语言scanf函数详解和示例

    文章目录 一.数据输入 二.断章取义 三.scanf输入 1.输入整数 2.输入字符 3.输入浮点数 4.输入字符串 5.输入多个内容 6.示例(book13.c) 四.注意事项 五.获取视频教程 六 ...

  5. C语言scanf函数详解

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

  6. C语言struct用法详解

    数组(Array),它是一组具有相同类型的数据的集合.但在实际的编程过程中,我们往往还需要一组类型不同的数据,例如对于学生信息登记表,姓名为字符串,学号为整数,年龄为整数,所在的学习小组为字符,成绩为 ...

  7. 第十章 结构体_C语言共用体(C语言union用法)详解

    通过前面的讲解,我们知道结构体(Struct)是一种构造类型或复杂类型,它可以包含多个类型不同的成员.在C语言中,还有另外一种和结构体非常类似的语法,叫做共用体(Union),它的定义格式为:  un ...

  8. C语言三目运算符用法详解

    对于条件表达式b ? x : y,先计算条件b,然后进行判断.如果b的值为true,计算x的值,运算结果为x的值:否则,计算y的值,运算结果为y的值. 一个条件表达式绝不会既计算x,又计算y.条件运算 ...

  9. C语言const用法详解(带实例)

    const与define区别 在C语言中const常用来定义常量,表示这个常量是不可以被修改的.define宏定义也可以用来表示一个常量.那么他们有那些区别呢! 1.预编译指令只是对值进行简单的替换, ...

  10. c语言printf()用法详解

    printf()函数是格式化输出函数, 一般用于向标准输出设备按规定格式输出 信息.在编写程序时经常会用到此函数.函数的原型为: int printf(const char *format, ...) ...

最新文章

  1. python 使用socks 爬虫_python爬虫基础之urllib的使用
  2. java final 接口_Java自学-接口与继承 final
  3. 把自己的项目布到服务器,如何把自己的开源项目发布到Pypi服务器
  4. PHP第五周答案,算法设计与分析第五周作业——Word Ladder
  5. [置顶] 风雨20年:我所积累的20条编程经验
  6. c语言 函数多个参数,C语言函数可变参数
  7. 微服务之迷思--转几位大牛的文章
  8. 配置sql server 2000以允许远程访问
  9. 第4.3节 Python中与迭代相关的函数
  10. mac使用brew update无反应解决办法
  11. 在百度超级链Xuper上部署智能合约并实现存证功能
  12. Telnet 窗口看不见字符
  13. 一名南京985AI硕士,CSDN博客专家
  14. es 怎么验证是否安装成功_ElasticSearch(ES)预警服务 Watcher安装以及探究
  15. 调研我国在需求分析方法、工具方面所做出的成果
  16. 网易校招内推-2023届技术类岗位
  17. 优化GNU/Linux桌面安装的九个步骤
  18. 【CNN】——涨点模块SE,CBAM,CA对比
  19. 2021年计算机类考研人数,2021年考研79所院校报考人数汇总
  20. RTMP直播到FMS中的AAC音频直播

热门文章

  1. php程序员自我描述_PHP程序员求职简历的自我评价范文
  2. Mysql 使用Maxscale读写分离,负载均衡
  3. java中的异或运算
  4. adprw指令通讯案例_S71200 ModbusTCP 通讯配置向导说明
  5. [概率统计]商务与经济统计知识点总结 Part 2
  6. android studio 配置应用生成多个dex
  7. 教你使用jmeter实现接口性能测试
  8. Linux服务器(CentOS7)基础信息设置之满足等保三级测评要求
  9. 基于微信小程序的毕业设计题目(24)php食堂餐厅就餐预约小程序(含开题报告、任务书、中期报告、答辩PPT、论文模板)
  10. 单节2A锂电池充电芯片方案,PD和QC快充充电器5-12V输入