该解析过程适用于scanf
、fscanf
、sscanf
,但sscanf
略有不同,因为不包含缓冲区或文件位置指示器,每次读取都从头开始。
基本概念
空白字符
空白字符是一些常用来分隔记号的字符,包括空格' '
,分页符'\f'
,换行符'\n'
,回车符'\r'
,水平制表符'\t'
,垂直制表符'\v'
。
格式字符串
格式字符串控制解析和转换格式,格式字符串一般包含:空白字符、普通字符、转换规格。
转换规格以%
开头,后面的数个字符控制转换方式,这些字符包含:
- 一个可选的分配抑制字符
*
- 一个可选的最大字段宽度
- 一个可选的接收对象大小描述符
- 转换类型
解析过程
解析过程从流的当前位置开始,按流方向依次进行。对应格式字符串从下标0开始,依次到字符串末尾。
解析过程先识别格式字符串,确定所需的字符,然后读取流,判断是否符合要求。如果解析成功,则更改文件位置指示器,并增加格式字符串下标,解析得到的字符会经过转换存入指定的内存区域。如果解析失败,文件位置指示器停在不满足要求的第一个字符处,已经存入的数据会保留,未处理的参数被忽略。解析失败会导致函数返回,但不会产生任何错误。
解析空白字符
连续读取流,直到遇到一个非空白字符(该字符未被读取),或者遇到文件末尾。
也就是说,如果格式字符串中有一个空白字符,在流中对应的位置可以有任意数量(包括0)个空白字符。
解析普通字符
流中的字符必须与对应格式字符串中的字符完全相同,如果某个字符不同,则解析失败,函数返回,该字符未被读取。
解析转换规格
如果转换类型是n
,不读取流内容,即不适用下面介绍的所有规则。
- 跳过所有的前置空白字符,除非转换类型是
c
、[
。 - 解析过程会尝试读取满足转换规格的最长字符序列,比如格式字符串为
"%d"
,流内容为123
,将会解析为整数123
而不是1
或12
。 - 如果遇到不满足转换规格的字符,则该转换规格的解析结束,该字符未被读取。该转换规格的解析结束时:
- 如果至少成功读取了一个字符,则解析成功,可继续解析下一个字段
- 如果遇到文件末尾,函数返回
- 如果没有读取到任何满足转换规格的字符,则解析失败,函数返回