【发布时间】:2019-06-11 01:12:19
【问题描述】:
几年前我使用 K&R 第 2 版 ANSI C 学习了 C。我一直在复习我的笔记,同时我正在从其他 2 本书中学习更现代的 C。
我注意到 K&R 在书中从不使用 scanf,除了在他们介绍它的一节。他们主要使用他们在书中编写的 getline 函数,一旦他们引入指针,他们会在本书后面更改该函数。 getline 与 gcc getline 不同,这给我带来了一些问题,直到我将 getline 的名称更改为 ggetline。
查看我的笔记我发现了这句话:
这种简化很方便,表面上很吸引人,而且它 工作,就它而言。问题是scanf不能正常工作 在更复杂的情况下。在 7.1 节中,我们说过调用 putchar 和 printf 可以交错。并非总是如此 的 scanf:如果您尝试混合呼叫,您可能会遇到莫名其妙的问题 通过调用 getchar 或 getline 来 scanf。更糟糕的是,事实证明 scanf 的错误处理不足以满足许多目的。它告诉你 转换是否成功(更准确地说,它会告诉您 成功转换了多少次),但它并没有告诉您更多信息 比那个(除非你问得非常仔细)。像atoi和atof,scanf 在处理 %d 或 %f 输入时停止读取字符 找到一个非数字字符。假设您已提示用户 输入一个数字,用户不小心输入了字母“x”。扫描 可能返回 0,表示它不能转换数字,但是 不可转换的文本(“x”)保留在输入流中,除非您 想办法把它去掉。
出于这些原因(以及其他几个原因,我不会费心 提)通常建议不要使用scanf 非结构化输入,例如用户提示。读起来好多了 像 getline 这样的整行(正如我们一直在做的那样 沿)然后以某种方式处理该行。如果该行应该 是单个数字,您可以使用 atoi 或 atof 转换它。如果 行有更复杂的结构,你可以使用 sscanf (我们将 一分钟后见面)来解析它。 (使用 sscanf 比使用 scanf 更好 因为当 sscanf 失败时,您可以完全控制自己的操作 下一个。另一方面,当 scanf 失败时,您将受到 它在输入流中离开你的位置。)
起初我以为这句话来自 K&R,但我在书中找不到。然后我意识到那是我上网的讲义,为多年前使用 K&R 书籍教授课程的人写的。
我知道 K&R 的书现在已经 30 年了,所以在某些方面它已经过时了。
这句话很老了,所以我想知道 scanf 是否仍然存在这种行为或已经改变了?
scanf 失败时是否仍将内容留在输入流中?例如上面:
假设您提示用户输入一个数字,并且用户 不小心输入了字母“x”。 scanf 可能返回 0,表示 它无法转换数字,但不可转换的文本( 'x') 保留在输入流中。
以下是否仍然正确?
putchar 和 printf 可以交错。并非总是如此 的 scanf:如果您尝试混合呼叫,您可能会遇到莫名其妙的问题 通过调用 getchar 或 getline 来 scanf。
自从写了上面的引用之后,scanf 有很大的变化吗?或者他们今天仍然如此?
我问的原因是,在我正在阅读的新书中,没有人提到这些问题。
【问题讨论】:
-
scanf()的行为没有显着改变——改变它会破坏工作代码(大量工作代码)。