`scanf` 应该如何处理不完整的指数部分?
What is `scanf` supposed to do with incomplete exponent-part?
例如 rc = scanf("%f", &flt);
输入 42ex
。 scanf
的实现将读取 42e
认为它会在此之后遇到数字或符号,并且在读取 x
时首先意识到它没有得到那个。此时它是否应该同时推回 x
和 e
?或者它应该只推回 x
.
我问的原因是 GNU 的 libc 将在随后调用 gets
return ex
表明他们已经推回了 x
和 e
,但标准说:
An input item is read from the stream, unless the specification includes an n specifier. An input item is defined as the longest sequence of input characters which does not exceed any specified field width and which is, or is a prefix of, a matching input sequence[245] The first character, if any, after the input item remains unread. If the length of the input item is zero, the execution of the directive fails; this condition is a matching failure unless end-of-file, an encoding error, or a read error prevented input from the stream, in which case it is an input failure.
我将其解释为因为 42e
是匹配输入序列的前缀(因为例如 42e1
将是匹配输入序列),这应该意味着它会考虑 42e
作为应读取的输入项,仅留下 x
未读。如果流只支持单字符回推,那实现起来也会更方便。
您对标准的解读是正确的。 C 标准中甚至还有一个例子,它说 100ergs of energy
不应该匹配 %f%20s of %20s
因为 100e
无法匹配 %f
.
但大多数 C 库似乎以不同的方式实现这一点,这可能是由于历史原因。我刚刚检查了 macOS 上的 C 库,它的行为类似于 glibc。 corresponding glibc bug 已作为 WONTFIX 关闭,Ulrich Drepper 的解释如下:
This is stupidity on the ISO C committee side which goes against existing
practice. Any change can break existing code.
例如 rc = scanf("%f", &flt);
输入 42ex
。 scanf
的实现将读取 42e
认为它会在此之后遇到数字或符号,并且在读取 x
时首先意识到它没有得到那个。此时它是否应该同时推回 x
和 e
?或者它应该只推回 x
.
我问的原因是 GNU 的 libc 将在随后调用 gets
return ex
表明他们已经推回了 x
和 e
,但标准说:
An input item is read from the stream, unless the specification includes an n specifier. An input item is defined as the longest sequence of input characters which does not exceed any specified field width and which is, or is a prefix of, a matching input sequence[245] The first character, if any, after the input item remains unread. If the length of the input item is zero, the execution of the directive fails; this condition is a matching failure unless end-of-file, an encoding error, or a read error prevented input from the stream, in which case it is an input failure.
我将其解释为因为 42e
是匹配输入序列的前缀(因为例如 42e1
将是匹配输入序列),这应该意味着它会考虑 42e
作为应读取的输入项,仅留下 x
未读。如果流只支持单字符回推,那实现起来也会更方便。
您对标准的解读是正确的。 C 标准中甚至还有一个例子,它说 100ergs of energy
不应该匹配 %f%20s of %20s
因为 100e
无法匹配 %f
.
但大多数 C 库似乎以不同的方式实现这一点,这可能是由于历史原因。我刚刚检查了 macOS 上的 C 库,它的行为类似于 glibc。 corresponding glibc bug 已作为 WONTFIX 关闭,Ulrich Drepper 的解释如下:
This is stupidity on the ISO C committee side which goes against existing practice. Any change can break existing code.