C语言篇:文件 - scanf解析

341 阅读2分钟

该解析过程适用于scanffscanfsscanf,但sscanf略有不同,因为不包含缓冲区或文件位置指示器,每次读取都从头开始。

基本概念

空白字符

空白字符是一些常用来分隔记号的字符,包括空格' ',分页符'\f',换行符'\n',回车符'\r',水平制表符'\t',垂直制表符'\v'

格式字符串

格式字符串控制解析和转换格式,格式字符串一般包含:空白字符普通字符转换规格

转换规格%开头,后面的数个字符控制转换方式,这些字符包含:

  • 一个可选的分配抑制字符*
  • 一个可选的最大字段宽度
  • 一个可选的接收对象大小描述符
  • 转换类型

解析过程

解析过程从流的当前位置开始,按流方向依次进行。对应格式字符串从下标0开始,依次到字符串末尾。

解析过程先识别格式字符串,确定所需的字符,然后读取流,判断是否符合要求。如果解析成功,则更改文件位置指示器,并增加格式字符串下标,解析得到的字符会经过转换存入指定的内存区域。如果解析失败,文件位置指示器停在不满足要求的第一个字符处,已经存入的数据会保留,未处理的参数被忽略。解析失败会导致函数返回,但不会产生任何错误。

解析空白字符

连续读取流,直到遇到一个非空白字符(该字符未被读取),或者遇到文件末尾。

也就是说,如果格式字符串中有一个空白字符,在流中对应的位置可以有任意数量(包括0)个空白字符。

解析普通字符

流中的字符必须与对应格式字符串中的字符完全相同,如果某个字符不同,则解析失败,函数返回,该字符未被读取。

解析转换规格

如果转换类型是n,不读取流内容,即不适用下面介绍的所有规则。

  • 跳过所有的前置空白字符,除非转换类型是c[
  • 解析过程会尝试读取满足转换规格的最长字符序列,比如格式字符串为"%d",流内容为123,将会解析为整数123而不是112
  • 如果遇到不满足转换规格的字符,则该转换规格的解析结束,该字符未被读取。该转换规格的解析结束时:
    • 如果至少成功读取了一个字符,则解析成功,可继续解析下一个字段
    • 如果遇到文件末尾,函数返回
    • 如果没有读取到任何满足转换规格的字符,则解析失败,函数返回