你真的懂C的格式化I/O吗?(下)

简介: 上一篇文章主要是总结了C语言下格式化输出相关的内容,这一节来总结一些格式化输入相关的内容。

系列文章目录


[C语言]之基本输入输出(格式化I/O)


回顾


上一篇文章主要是总结了C语言下格式化输出相关的内容,这一节来总结一些格式化输入相关的内容。


格式化输入


下面是ANSI C定义的标准的输入函数族:


#include <stdio.h>
int scanf(const char *format, ...);
int sscanf(const char *string, char *format, ...);
int fscanf(FILE *stream, const char* fromat, ...);


下面以scanf为例来说明一下格式化输入的用法,sscanf、fscanf的使用方式类似。


int scanf(const char *format, ...);


scanf函数从标准输入中读取字符序列,并按照format中的格式说明对字符序列进行解释,并把结果保存到其余 的参数中。关于scanf需要注意的几点如下:


  • 所有的参数都是指针类型


  • 当scanf扫描完format格式串时,或者碰到某些输入无法与格式控制说明匹配的情况时,该函数终止,并返回,返回值为成功匹配并赋值的输入项的个数,所以函数的返回值可以用来确定已匹配的输入项的个数。


  • 如果达到文件结尾,该函数将返回EOF。


  • 返回0表示下一个输入字符与格式串中的第一个格式说明不匹配。


  • 下一次调用scanf函数将从上一次转换的最后一个字符的下一个字符开始继续搜索。

格式说明format用于控制输入的转换,其包括如下几部分:


[空格或制表符][普通字符(除%之外)]%[*][最大宽度]转换字符
其中,[]中的内容为可选字段。


字符 含义
空格或制表符 这些字符在处理过程中将被忽略
普通字符(不包括%) 用于匹配输入流中下一个非空白字符
转换说明 依次由一个%,一个可选的赋值禁止符*、一个可选的数值(指定最大字段宽度)
h或l或L 指定目标对象的宽度
转换字符 转换字符结尾,下表会介绍
这里需要注意的是,如果转换说明中存在*,则跳过该输入字段,不进行赋值。
输入字段定义为一个不包括空白符的字符串,其边界定义为到下一个空白符或达到指定的字段宽度。这说明scanf函数将越过行边界读取输入,因为换行符也是空白符。(空白符包括空格符、横向制表符、换行符、回车符、纵向制表符以及换页符)。


转换字符定义如下:


字符 输入数据 参数类型
d 十进制整数 int* 类型
i 整数 int*整型,可以是八进制(以0开头)或十六进制(以0x或0X开头)
o 八进制整数(可以以0开头也可以不以0开头) int*类型
u 无符号十进制整数 unsigned int*类型
x 十六进制整数(可以以0x或0X开头,也可以不以其开头) int *类型
c 字符 char *类型
s 字符串(不加引号) char *类型,指向一个足以存放该字符串(包括字符串末尾'\0')的字符数组。字符创的末尾将自动添加一个结束符‘\0’
e/f/g 浮点数,它可以包括正负号(可选)、小数点(可选)、指数部分(可选) float *类型
% 不进行任何赋值操作


转换字符d、i、o、u及x的前面可以加上字符h或l。前缀h表明参数表的相应参数是一个指向short类型而非int类型的指针,前缀l表明参数表的相应参数是一个指向long类型的指针。类似地,转换说明e、f和g的前面也可以加上前缀l,它表明参数表的相应参数是一个指向double类型的而非float类型的指针。


下面通过几个示例说明一下如何进行格式化输入操作。


  1. 示例一:使用scanf解析格式如24/01/2021日期


int day, year;
char monthname[20];
scanf("%d/%2s/%d", &day, monthname, &year);//注意:%2s表示字符串的宽度为2
printf("day:%d, month:%s, year:%d.\n", day, monthname, year);
输入:24/01/2021
输出:day:24, month:01, year:2021


  1. 示例二:使用sscanf解析格式如24/01/2021日期


int day, year;
char monthname[20];
char *date = "24/01/2021";
sscanf(date, "%d/%2s/%d", &day, monthname, &year);
printf("day:%d, month:%s, year:%d.\n", day, monthname, year);
输出:day:24, month:01, year:2021


参考资料:《C程序设计语言》,一本每个C程序员都要精读的书,向伟大的祖师爷 Brian W.Kernighan & Dennis M.Ritchie致敬!


sscanf与scanf的format格式类似,不同的地方是sscanf数据源是个字符串。



相关文章
|
10月前
|
机器学习/深度学习 缓存 自然语言处理
DeepSeek背后的技术基石:DeepSeekMoE基于专家混合系统的大规模语言模型架构
DeepSeekMoE是一种创新的大规模语言模型架构,融合了专家混合系统(MoE)、多头潜在注意力机制(MLA)和RMSNorm归一化。通过专家共享、动态路由和潜在变量缓存技术,DeepSeekMoE在保持性能的同时,将计算开销降低了40%,显著提升了训练和推理效率。该模型在语言建模、机器翻译和长文本处理等任务中表现出色,具备广泛的应用前景,特别是在计算资源受限的场景下。
1316 29
DeepSeek背后的技术基石:DeepSeekMoE基于专家混合系统的大规模语言模型架构
|
SQL 关系型数据库 MySQL
乐观锁在分布式数据库中如何与事务隔离级别结合使用
乐观锁在分布式数据库中如何与事务隔离级别结合使用
|
JavaScript 前端开发 开发者
Layui layer 弹出层的使用【笔记】
本文介绍了Layui的layer弹出层组件的使用方法,包括如何通过在线CDN引入Layui的CSS和JS文件,以及如何使用layer.open(options)开启弹出层和layer.close(index)关闭弹出层。文章详细说明了弹出层类型的分类、options选项的参数配置,以及回调函数的使用。通过示例代码,展示了如何创建不同类型的弹出层,包括对话信息框、页面层、内联框架层、加载层和tips层。
|
监控 网络协议 网络架构
OSPF的DR/BDR选举机制:原理与应用
OSPF的DR/BDR选举机制:原理与应用
2236 4
|
XML 数据格式 Python
YOLOv5入门实践(3)——手把手教你划分自己的数据集
YOLOv5入门实践(3)——手把手教你划分自己的数据集
5401 0
YOLOv5入门实践(3)——手把手教你划分自己的数据集
|
缓存 JavaScript 前端开发
成功解决:npm 版本不支持node.js。【 npm v9.1.2 does not support Node.js v16.6.0.】
这篇文章介绍了如何解决npm版本与Node.js版本不兼容的问题,提供了查看当前npm和Node.js版本的步骤,以及如何根据Node.js版本选择合适的npm版本并进行升级的详细指导。
成功解决:npm 版本不支持node.js。【 npm v9.1.2 does not support Node.js v16.6.0.】
|
运维 安全 网络安全
"革新远程访问体验:Docker化部署webssh2,一键启动Web SSH客户端,让远程管理如虎添翼!"
【8月更文挑战第2天】Docker作为软件开发与运维的关键工具,以其轻量级、可移植及强隔离特性简化了应用部署。结合webssh2这一开源Web SSH客户端,可通过浏览器安全便捷地访问SSH服务器,无需额外软件。首先确保已安装Docker,接着拉取webssh2镜像并运行容器,映射端口以便外部访问。配置好SSH服务器后,通过浏览器访问指定URL即可开始SSH会话。此方案不仅提升了用户体验,还加强了访问控制与系统安全。
1212 7
|
边缘计算 Kubernetes Cloud Native
恭喜我的同事黄玉奇入选开放原子开源基金会TOC
近日,开放原子开源基金会技术监督委员会(TOC)举行第 32 次例会。经过投票,阿里云云原生应用平台高级技术专家黄玉奇正式当选为开放原子开源基金会 TOC 成员。
恭喜我的同事黄玉奇入选开放原子开源基金会TOC
|
存储 算法 前端开发
数据结构与算法之八 队列
数据结构与算法之八 队列
94 0