【问题标题】:Buffered and Unbuffered inputs in CC中的缓冲和非缓冲输入
【发布时间】:2013-12-19 00:22:25
【问题描述】:

有什么方法可以确定inputbuffered 还是unbuffered(除了手册页)?我们不能通过查看函数的名称来弄清楚吗? 也适用于echoingnonechoing... 如需快速参考,在哪里可以找到包含 BufferedUnbufferedechoingnonechoing 输入的详细信息的列表?

【问题讨论】:

  • 抱歉,您说的是“除了手册页”。已删除评论。仅供参考 setbuf 可能会有所帮助。
  • 我认为没有一种可移植的方法来检测特定的打开文件流 (FILE *) 是缓冲的还是未缓冲的。无论如何,您为什么需要知道?
  • 我不想在运行时知道它。但是有没有办法知道哪个函数是缓冲的或非缓冲的或回显的或非回显的......通过查看函数名称,有可能吗?否则任何告诉哪个函数被缓冲,哪个函数没有被缓冲的链接都会有所帮助。

标签: c input buffer


【解决方案1】:

所有FILE读取的stdio.h函数可能表现出任一“缓冲”或“非缓冲”行为,并且任一 “回声”或“非回声”行为。控制这些东西的不是你使用的函数,而是流和/或其底层文件描述符的设置。

  • 标准库函数setvbuf 可用于启用或禁用 C 库对输入(和输出)的缓冲。这对操作系统的缓冲没有影响。有三种可能的模式:“完全缓冲”(大量读取或写入); “行缓冲”(缓冲直到读取或写入 '\n' 字符,但不超过此);和“无缓冲”(所有读取和写入立即转到操作系统)。

  • 新的FILE 对象(包括stdin 和朋友)的默认缓冲是实现定义的。 Unixy C 库通常默认所有FILEs 为完全缓冲,但有两个例外。 stderr 默认为无缓冲。对于任何其他FILE,如果setvbuf 在第一次实际读取或写入时尚未在其上使用,并且isatty 对底层文件描述符为真,则FILE 变为行缓冲。

  • 一些 C 库提供扩展功能,例如__flbf 和 Linux 和 Solaris 上的朋友,感谢您回读 一些setvbuf 控制的设置。请记住,如上所述,如果没有明确设置,缓冲模式可能会在第一次实际读取或写入时发生变化。

如果输入来自文件,setvbuf 是您拥有的唯一旋钮。如果输入来自某种通信渠道,则可能还有其他旋钮:

  • 在符合 POSIX 的系统(阅读“除 Windows 之外的所有系统”)上,程序可以请求多种不同模式中的任何一种进行终端输入。其中,最重要的区别是between "canonical" and "noncanonical"。规范模式下的终端同时显示缓冲和回显。 (如果没有使用 setvbuf 禁用它,则此缓冲与 C 库可能执行的缓冲分开。)非规范模式允许您分别切换缓冲和回显。 low-level POSIX terminal interface 广泛而复杂,允许您读取和写入所有这些设置。

  • 如果您想将终端置于非规范模式,在针对低级 POSIX API 编写一堆代码之前,您应该首先考虑是 readline 还是 @ 987654327@图书馆将使您的生活更轻松。

  • 如果您正在从管道中读取数据,那么您将受制于写入它的人;您无法控制获得的块的大小。

  • 如果您正在从套接字读取,您可能可以通过仔细使用 recvmsg 来控制获得的块的大小,但不能保证.

  • 我不知道它在 Windows 上如何。

【讨论】:

  • +1 阅读您的帖子后,我删除了我的帖子。感谢您的回答。
  • 我有几个问题要问你。谁为标准库函数设置 setvbuf? (标准库函数是否默认行缓冲?)使用哪个函数我们可以设置回显和非回显功能?使用 setvbuf 控制缓冲区的一些示例会很有帮助。谢谢。
  • @NishithJainMR 我已在答案文本中添加了对默认 stdio 缓冲行为的解释。我不想提供比这里更多的回声信息,因为我不想给人留下关闭回声很简单的印象。执行此操作的实际系统调用很简单,但它们会产生一大堆令人惊讶的后果。在几乎所有情况下,都应该使用ncursesreadline 来代替;这些提供了一个更高级别的 API,可以消除所有这些后果。
  • 在windows上(至少mingw)所有文件都是完全缓冲的,包括stdout甚至stderrsetbuf()setvbuf() 可用。
【解决方案2】:

ISO/IEC 9899-1999 C99 语言标准

5.1.2.3 程序执行

...

5) 交互设备的输入和输出动态应按照 7.19.3。这些要求的目的是无缓冲或行缓冲输出 尽快出现,以确保提示消息实际出现在之前 等待输入的程序。 ...

7.19.3 文件

...

3) 当一个流没有缓冲时,字符应该从源或在 尽快到达目的地。否则可能会累积字符并 作为块传输到主机环境或从主机环境传输。当流完全缓冲时, 字符旨在作为一个块传输到主机环境或从主机环境传输 一个缓冲区被填满。当流被行缓冲时,字符旨在 当换行符被发送到主机环境或从主机环境传输 遭遇。此外,字符旨在作为块传输到主机 填充缓冲区时的环境,在无缓冲流上请求输入时,或 当在需要传输的行缓冲流上请求输入时 来自宿主环境的字符。对这些特性的支持是 实现定义,并且可能通过 setbuf 和 setvbuf 函数受到影响。 ...

7) 程序启动时,预定义了三个文本流,不需要显式打开 — 标准输入(用于读取常规输入)、标准输出(用于写入 常规输出)和标准错误(用于写入诊断输出)。和最初一样 打开,标准错误流没有完全缓冲;标准输入和标准 当且仅当可以确定流不引用时,输出流才被完全缓冲 到交互式设备。

【讨论】:

    【解决方案3】:

    您可以将缓冲区与文件(包括stdin)关联到setvbuf()。您可以将缓冲模式更改为 full、line 或 none。

    【讨论】:

    • 是的,但这无助于检测特定的开放流是缓冲的还是非缓冲的,这就是我认为问题所要问的。
    猜你喜欢
    • 2012-10-08
    • 2016-07-14
    • 1970-01-01
    • 2010-11-29
    • 2014-01-30
    • 2017-09-06
    • 2021-10-08
    • 2011-12-28
    相关资源
    最近更新 更多