RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1133936
Accepted
Danny
Danny
Asked:2020-05-31 02:53:47 +0000 UTC2020-05-31 02:53:47 +0000 UTC 2020-05-31 02:53:47 +0000 UTC

C 中的数据缓冲

  • 772

大家好。对以下问题感兴趣。C 中标准流的输入/输出(stdin / stdout)是缓冲的,这意味着进入这些流的所有信息都累积在缓冲区中,然后写入文件(控制台)。我读到缓冲区已满时会发生录制。缓冲区大小是多少?我认为大小在几千字节左右波动,但是为什么,例如,如果有一个 printf() 函数后跟 scanf(),那么传输到 printf() 的内容会显示在屏幕上,而输出被缓冲并且缓冲区没有完全填满,或者仍然存在将缓冲区中的内容写入文件的时刻?对此,我也无法理解为什么需要flash()。请用简单的语言解释。谢谢

c++
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Fat-Zer
    2020-05-31T19:46:09Z2020-05-31T19:46:09Z

    C 标准定义了三种流缓冲¹:

    • 无缓冲流(无缓冲) - 程序/libc 端没有缓冲:所有数据都会尽快传输到操作系统/设备。
    • 完全缓冲(full buffered)——数据被写入缓冲区,并且只有在它已满或被强制刷新时才会真正输出。
    • 行缓冲( line buffered ) - 数据被缓冲,但如果流遇到行尾字符 ( \n),如果缓冲区已满或强制刷新,则输出。此外,当某些(通常是另一个,例如)行缓冲流尝试读取某些内容并且其输入缓冲区为空时,所有行缓冲输出流(特别是)都会被刷新。stdoutstdin

    对于标准流,还保证:

    • stderr没有完全缓冲。实际上,在几乎所有实现中,它都是无缓冲的。

    • stdin并且stdout只有在它们不指向交互式设备时才能完全缓冲(即 I/O 被重定向到文件,而不是来自控制台/终端)。在几乎所有 POSIX 系统上,它们都是线性缓冲的。但是标准库的 msvc 实现不支持线性缓冲流,因此它们在那里没有缓冲。

    您可以使用 更改缓冲类型并设置自己的缓冲区setvbuf()。


    缓冲区大小是多少?

    依赖于实现,它在宏中可用BUFSIZ。大小保证大于256,典型值:512-8k。但是这个缓冲区的内部结构和算法不是专门的,所以这并不意味着会从文件中读取/写入/写入这么多字节。

    那为什么,例如,如果有一个 printf() 函数后跟 scanf(),那么传递给 printf() 的内容会显示在屏幕上,而输出是缓冲的,缓冲区没有完全填满

    如上所述,默认情况下,与终端关联的流要么是行缓冲的,要么是无缓冲的。在第一种情况下,输出printf()在当时立即出现在屏幕上,而在第二种情况下——如果它printf()以新行结束,或者在执行时立即出现scanf()。在此示例中可以看到行为上的差异:

    printf("Hello ");
    sleep(10);
    printf("world!\n");
    

    在 win32上,它也会Hello在 10 秒后显示world!,而在 * nix 上,它也会在 10 秒后显示。

    或者仍然存在将缓冲区中的内容写入文件的时刻?

    与终端不同,文件通常是完全缓冲的,例如在这个版本中:

    FILE *f = fopen("foo", "w")
    fprintf(f, "Hello world!\n");
    getc(stdin);
    fclose(f);
    

    在延迟期间,getc()文件将为空。

    除了完全填充的情况外,当文件关闭时( )强制刷新缓冲区fclose(),程序正确终止(exit()或return从main(),但不一定是何时abort())。此外,一些其他标准函数可以调用fflush(),例如,fseek()或从打开的文件中读取函数以进行读/写,但这已经取决于实现。

    对此,我也无法理解为什么需要flash()。

    fflush()实际上需要强制将缓冲区的内容写入文件。在上面的例子中,如果你添加fflush()before getc(),它将"Hello world!"保证被写入文件。如果你对术语再多找错,那么fflush()缓冲区的内容会“传递给执行环境”,实际上这并不意味着它可以保证保存在磁盘上。操作系统有自己的缓冲设施。

    还值得记住的是,它只fflush()影响输出缓冲区,对输入流没有影响。


    ¹ 通​​常,所有这些都是为输入流和输出流定义的,但实际上,这实际上不会影响输入流的行为。

    • 8
  2. AlexGlebe
    2020-05-31T14:34:59Z2020-05-31T14:34:59Z

    默认情况下,输入和输出缓冲区是同步的。这意味着来自不同流的任何序列都必须具有已保存的序列。例如,如果缓冲"type x:"并按10,那么输出应该是"type x:10",而不是"10 type x:"。

    如果它scanf要求数据,则默认情况下它会输出按下的字母,并且输出缓冲区与fflush输出同步введите x:。您可以禁用屏幕上输入字符的显示,然后为了让用户了解他们想要从他那里得到什么,那么您需要清除缓冲区,否则屏幕上将没有请求введите x:。例如,当您要求输入密码时,就会发生这种情况。

    如果输出到文件,则数据将写入 C 缓冲区,但不会写入操作系统缓冲区。在同步期间,C 缓冲区被清除并写入 OS 缓冲区。所以更有可能在危急情况下将数据写入文件。(电/内存/处理器)

    • 3

相关问题

  • 编译器和模板处理

  • 指针。找到最小数量

  • C++,关于枚举类对象初始化的问题

  • 函数中的二维数组

  • 无法使用默认构造函数创建类对象

  • C++ 和循环依赖

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5