c - K&R C 书关于 scanf 如何处理格式字符串中的空格和制表符的问题?

标签 c scanf kernighan-and-ritchie ansi-c

阅读 Brian Kernighan 和 Dennis Ritchie 的名著 The C programming language ANSI C second edition,我在第 7 章(第 7.4 节,第 157 页)中找到了下面这段描述格式字符串的段落扫描:

[...]

The format string usually contains conversion specifications, which are used to control conversion of input. The format string may contain:

  • Blanks or tabs, which are ignored.

[...]

我记得现在我们在格式字符串中使用空格来告诉编译器跳过空格,直到它找到一个非空格字符。因此,我认为由于多年来 C 语言的更新,该段不再有效。我说的对不对? 🤔

最佳答案

C bible 记录了 scanf() 的过时版本。 scanf() 的早期版本用于忽略输入字符串中的所有空格,因此格式字符串中的空格也被忽略。这种行为在 C 被 ANSI 规范化和后来被 ISO 规范化之前就已经改变了。

第二版的封面确实提到了ANSI-C,但是关于scanf(),它的描述对于ANSI及以后的版本是不正确的。

事实上 man page from Version 7 ,1979 年贝尔实验室的原始 Unix 已经记录了这一点:

The control string usually contains conversion specifications, which are used to direct interpretation of input sequences. The control string may contain:

  1. Blanks, tabs or newlines, which match optional white space in the input.
  2. An ordinary character (not %) which must match the next character of the input stream.
  3. Conversion specifications, consisting of the character %, an optional assignment suppressing character *, an optional numerical maximum field width, and a conversion character.

没有实际的编译器支持书中记录的古老行为。在研究了 K&R 中的这个令人惊讶的错误之后,似乎 scanf() 几乎从 Unix 系统诞生的第一天起就有了当前的行为。 scanf() 一直很古怪且容易出错,这个伟大的发现增加了一系列的陷阱。

您可以找到 errata 的列表更正了本书第二版中的一些错误,但未列出这一错误。

为了进一步调查,可以在Dennis Ritchie's home page上找到大量历史信息。 , Brian Kernighan's page on the book , 和 here , 和 bitsavers.org archives .

关于c - K&R C 书关于 scanf 如何处理格式字符串中的空格和制表符的问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61704170/

相关文章:

c - 在 C : OSdev 中绘制像素

c - C 读取十六进制数并验证其位数

c - getchar() 函数是否有自己的缓冲区来存储剩余的输入?

c - 函数声明与原型(prototype)的替代 (K&R) C 语法

c - 如何在 C 中以任何预处理器指令形式定义一组配置

c - get_sp() 函数如何工作?

c - 使用 float 作为正确类型的输入验证

c - fscanf() fclose() 或读取文件退出并结束程序

c - KR练习4.7 Ungets功能测试

c - 即使未声明为静态,变量仍保持其状态