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

时间:2015-01-14 08:04:40

标签: c input buffer stdin scanf

例如,当我执行scanf("%s",arg);时:终端允许我输入文本,直到遇到换行符,但它只存储arg变量中的第一个空格字符。休息时间仍在缓冲区中。

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

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

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

假设arg属于正确类型。

我的理解似乎在根本上是错误的。如果有人可以解释这些东西,我将非常感激。

3 个答案:

答案 0 :(得分:2)

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

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

如果你的意思是"它是如何在封面下处理的?",这是一个不同的问题。

我对此的第一反应是"它并不重要"。 ISO标准规定了语言的工作方式,它描述了一个虚拟机"能做到这一点。如果您遵守机器的规则,您就不必担心事情会如何发生。

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

为了提高效率,底层软件可能不会将任何数据提供给实现,直到它有一个完整的行(尽管这当然很可能是可配置的,例如为终端设置原始模式)。这意味着像backspace这样的东西可以更改已输入的字符,而不是插入到流中。

它可能(比如使用GNU readline()库在发送字符之前允许在线上进行各种真正奇特的编辑。没有什么可以阻止底层软件打开{{{ 1}}会话,允许您输入数据,并且只在您退出后才提供: - )

答案 1 :(得分:1)

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

例如:在按下enter之前可以读取字符,特别是如果缓冲区也可以被禁用。

答案 2 :(得分:1)

我认为,它与how much无关,而是格式说明符所说的。

根据C99,第7.19.6.2章第2段(适用于fscanf()

  

fscanf函数在流控制下从流指向的流中读取输入   格式指向的字符串,指定允许的输入序列和方式   它们将被转换为赋值,使用后续参数作为指针   对象接收转换后的输入。

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