c - `scanf` 应该如何处理不完整的指数部分?

标签 c language-lawyer c99 glibc

rc = scanf("%f", &flt); 为例,输入 42exscanf 的实现会读取 42e 认为它会在之后遇到一个数字或符号,但在读取 x 时首先意识到它没有得到那。此时它是否应该同时推回 xe?或者它应该只推回 x

我问的原因是 GNU 的 libc 将在随后调用 gets 时返回 ex 表明他们已经推回了 xe,但标准说:

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.

关于c - `scanf` 应该如何处理不完整的指数部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40405417/

相关文章:

c++ - Code::Blocks C/C++ windows.h 缺少 fatal error

c++ - std::less<void> 和指针类型

c - int foo(int Grade, void* Factor) - 如何在函数内部使用该因子?

c++ - 使用线程池的 std::async 的 Visual C++ 实现是否合法

stdout - 默认情况下,stdout 行是缓冲的、无缓冲的还是不确定的?

c - 全局初始化数组的未使用索引?

c - 如何模拟网页浏览器与https服务器交互

将 char *buffer 中的数据复制/移动到 char info[4][10] 的多维数组

c++ - 这是怎么定义的?

c++ - operator== 使用 msvc 编译,但不使用 gcc 和 clang 编译