假设我们有
int n;
sscanf(" 42", "%2d", &n);
n
应该是4(空格由“%2d”占据)还是42(忽略空格,使scanf读取3个字符)?
ideone implementation读取3个字符
答案 0 :(得分:4)
sscanf()
的POSIX规范
对于处理过程非常清楚:
格式是一个字符串,由零个或多个指令组成。每个指令由以下之一组成:一个或多个空格字符(
resolve
,<space>
,<tab>
,<newline>
或<vertical-tab>
);普通字符(既不是'<form-feed>
'也不是空格字符);或转换说明。每个转换规范都由字符'%
'[CX] introduced或字符序列“%n $”引入,其后依次显示以下内容:...
作为转换规范的指令定义了一组匹配的输入序列,如下文针对每个转换字符所述。转换规范应按以下步骤执行。
除非转换规范包括
%
,isspace
,[
或{{1},否则将跳过输入的空白字符(由c
指定) }}转换说明符。除非转换说明中包含
C
转换说明符,否则应从输入中读取项目。输入项目应定义为最长的输入字节序列(不超过任何指定的最大字段宽度,可以根据转换说明符以字符或字节为单位进行度量),它是匹配序列的初始子序列。输入项目后的第一个字节(如果有的话)应保持未读状态。如果输入项的长度为0,则转换规范的执行将失败;否则,转换规范的执行将失败。这种情况是匹配失败,除非文件末尾,编码错误或读取错误阻止了来自流的输入,在这种情况下,这是输入失败。
如果空格被转换规范(n
)跳过,则不算作字段宽度的一部分;跳过会在进行任何计数之前发生。
C11 §7.21.6.2 The fscanf
function中的等效规范非常相似(但当然不包括“ C扩展”标记)。
答案 1 :(得分:3)
scanf的“最大字段宽度”包含空格吗?
[
和c
是。
没有其他说明符。
"%n"
不适用。
fscanf()
(C11dr§7.21.6.27-9)
7 ...在以下步骤中执行转换说明:
输入的8个空白字符(由isspace函数指定)已跳过,除非规范中包含
[
,c
或n
说明符。9从流中读取一个输入项,...一个输入项定义为最长的输入字符序列,不超过任何指定的字段 width 和.... >
width 适用于领先的输入空格字符消耗。
此外,在我阅读规范时,如果转换失败,则输入的空白字符仍会被消耗。
答案 2 :(得分:1)
在BSD手册页上:
除了这些标志之外,可能还有一个可选的最大字段宽度, 用%和转换之间的十进制整数表示。如果没有宽度 给定,使用默认值``infinity''(下面有一个例外);除此以外 在处理转换时最多扫描这么多字节。如果是 lc,ls和l [转换时,字段宽度指定了 多字节字符将被扫描。在转换开始之前,大多数转换会跳过空白;此空白不计入字段 宽度。
Linux手册页具有
一个可选的十进制整数,指定最大字段宽度。阅读 的字符数在达到此最大值或不匹配时停止 找到字符,以先发生的为准。大多数转化会放弃初始 空格字符(以下有例外说明),并将这些字符丢弃 字符不计入最大字段宽度。字符串输入转换存储一个终止的空字节('\ 0')来标记输入的结尾。的 最大字段宽度不包含此终止符。
都指定空白不计入字段宽度。