系列文章目录
回顾
上一篇文章主要是总结了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类型的指针。
下面通过几个示例说明一下如何进行格式化输入操作。
- 示例一:使用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
- 示例二:使用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数据源是个字符串。