C 中的 scanf() 期间数据如何从输入流流入输入缓冲区?

How does the data flow from input stream into the input buffer during scanf() in C?

例如,当我执行 scanf("%s",arg); 时:终端允许我输入文本,直到遇到换行符,但它最多只存储 arg 变量中的第一个 space 字符。其余部分保留在缓冲区中。

scanf("%c", arg); :在这种情况下,它还允许我在终端中输入文本,直到我给出一个换行符,但只有一个存储在 arg 中,而其余的则保留在缓冲区中。

scanf("%[^P]", arg); :在这种情况下,即使给它一个换行符,我也可以在终端中输入文本,直到我在其中输入 'P' 并按回车键(换行符),然后将所有内容传输到输入缓冲区。

如何确定输入流中一次要传输多少数据到输入缓冲区?

假设 arg 是正确的类型。

这里我的理解好像根本就错了。如果有人能解释一下这些东西,我将不胜感激。

缓冲区和原始编辑功能由操作系统提供。 如果您可以将终端设置为 "raw mode",您将看到不同的行为。

例如:在按下回车键之前字符可能可供读取,尤其是在缓冲区也可以被禁用的情况下。

如何确定的?由格式字符串本身决定。

scanf 函数将读取项目,直到它们不再匹配给定的格式说明符。然后它停止,将第一个 "non-compliant" 字符留在缓冲区中。

如果你的意思是 "how is it handled under the covers?",那就是另一回事了。

我对此的第一反应是 "it doesn't matter"。 ISO 标准规定了该语言的工作方式,并描述了能够做到这一点的 "virtual machine"。只要遵守机器的规则,就不用担心背后的事情是怎么发生的。

我的第二个答案可能更令人满意,但非常依赖于实现。

为了效率,底层软件可能不会向实现提供 任何 数据,直到它有一个完整的行(当然这可能是可配置的,例如设置终端的原始模式)。这意味着退格键之类的东西可能 更改 已经输入的字符,而不是插入到流中。

它可能(例如 GNU readline() 库允许在传送字符之前在线进行各种非常花哨的编辑。没有什么可以阻止底层软件甚至打开 vim 会话允许您输入数据,并且只有在您退出时才会传送它:-)

我认为,这与 how much 无关,而与格式说明符有关。

根据 C99,第 7.19.6.2 章第 2 段,(针对 fscanf()

The fscanf function reads input from the stream pointed to by stream, under control of the string pointed to by format that specifies the admissible input sequences and how they are to be converted for assignment, using subsequent arguments as pointers to the objects to receive the converted input.

关于格式说明符,您需要参考第 12 段。