【问题标题】:Requesting explanation for the following code snippet from Teach Yourself C pg#234从 Teach Yourself C pg#234 请求对以下代码片段的解释
【发布时间】:2022-12-18 21:20:13
【问题描述】:

以下代码 sn-p 取自自学 C经过赫伯特席尔特第 234 页。

#include <stdio.h>

int main(void)
{
    char ch;
    do
    {
        ch = getchar(); //suppose asdf is input
        putchar('.');
    } while (ch != '\n');
    return 0;
}

哪个返回,

asdf
.....
Process returned 0 (0x0)   execution time : 0.050 s
Press any key to continue.

在此 sn-p Herbert Schildt 之后写道:“您将在屏幕上看到的不是在每个字符之间打印一个句点,而是您在按 ENTER 键之前键入的所有字母,后跟一串句点。”

我被这个 sn-p 困住了 while。我尝试了 sn-p 的一些变体以更好地理解它,这提出了比回答更多的问题。这其实违背了我目前的理解。而不是打印出上面的输出,我目前的理解建议以下输出:

asdf //input asdf
.
asd //input asd
.
\n //hit ENTER
.
Process returned 0 (0x0)   execution time : 0.050 s
Press any key to continue.

通过以上介绍,我有以下疑问:

  1. 上面的 sn-p 是如何循环的?
  2. 我现在有什么问题直觉

【问题讨论】:

  • getchar() 读取单个字符。循环每次迭代读取一个字符,并在读取 '\n' 时退出。然后程序结束。运行此程序时,您只能输入一行。我希望新阅读代码的人会看到类似“a.s.d.f..”的内容。您看不到这一点的原因是 I/O 被缓冲并且只有当缓冲区被刷新到输出设备时才会输出到屏幕。在这个程序中,输出缓冲区通常只会在程序退出时被刷新。 See this question
  • 我对这本书不熟悉,但是名字赫伯特席尔特为我举起红旗。我记得那个作者以写关于 C 的坏书而闻名。You might want to take a look at this, though it is about a different C book by the same author.
  • 关于如何处理“键盘”输入的一些实际细节,以及所涉及的各个子系统之间的交互,可能会非常复杂。我可以推荐this answerthese course notesthis other question

标签: c while-loop


【解决方案1】:

从 C 标准:

C17 § 7.21.3p7:

当且仅当可以确定流不是指交互设备时,标准输入和标准输出流才被完全缓冲

来自 ANSI C 标准:

描述:

“putchar”向标准输出“stdout”输出一个字符,并返回写入的字符。

默认情况下,所有输出流(包括“stdout”和“stderr”)通常都会被缓冲。这意味着许多字符在内部保存在称为缓冲区的内存区域中。当缓冲区已满时,字符将作为一个组写出。如果程序从有缓冲输出的终端请求输入,输出会自动“刷新”到终端,之后输入函数开始读取输入。

由此,您可以推断在看到 之前,getchar() 没有得到任何东西。

【讨论】:

    【解决方案2】:

    Schildt 以不真正了解 C 语言和程序运行环境(除其他事项外)之间的区别而闻名 [1, 2, 3]。另一本书可能会更好地为您服务。

    但至于你的具体问题,这就是一般来说发生。

    用户按下 asdf 键。 shell(例如 bash、cmd.exe)可以选择立即将它们发送到程序,但它通常将它们存储在缓冲区中,直到 1)缓冲区变满或 2)用户输入换行符。本书假设缓冲以这种方式发生。 shell 还会频繁地回显您正在键入的字符,因此在键入 asdf 后,“asdf”会出现在屏幕上。

    因此,当您键入 Enter 时,程序会立即接收所有输入(在标准输入流中)。 (从这一点开始,行为完全由 C 控制。)但是 getchar() 一次只获取一个,所以每次通过循环,上面写着字符,然后打印“.”。读取(并打印)换行符后,循环退出。

    【讨论】:

    • 很好的答案,虽然它与“shell(例如 bash、cmd.exe)”无关——你所谈论的处理发生在“系统”的某个地方(通常是操作系统和终端驱动程序)。
    猜你喜欢
    • 1970-01-01
    • 2014-04-04
    • 2014-02-15
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 2015-06-23
    • 2018-06-11
    • 2018-05-09
    相关资源
    最近更新 更多