除非换行符在格式字符串中,否则为什么在调用后printf不会刷新? 这是POSIX行为吗? 每次如何立即使printf刷新?


#1楼

stdout已缓冲,因此仅在换行符输出后输出。

要立即获得输出,请执行以下任一操作:

  1. 打印到stderr。
  2. 使stdout无缓冲。

#2楼

要立即刷新,请调用fflush(stdout)fflush(NULL)NULL表示刷新所有内容)。


#3楼

您可以使用fprintf到没有缓冲的stderr。 或者,您可以在需要时刷新标准输出。 或者,您可以将stdout设置为unbuffered。


#4楼

默认情况下, stdout流是行缓冲的,因此仅在到达换行符后(或被告知时)才显示缓冲区中的内容。 您有几种选择可以立即打印:

打印到stderr而不是使用fprintf ( 默认情况下 stderr是未缓冲的 ):

fprintf(stderr, "I will be printed immediately");

在需要使用fflush时冲洗stdout:

printf("Buffered, will be flushed");
fflush(stdout); // Will now print everything in the stdout buffer

编辑 :从下面的安迪·罗斯的评论,您还可以通过使用setbuf禁用对stdout的缓冲:

setbuf(stdout, NULL);

#5楼

可能是因为效率高,并且因为如果您有多个程序写入一个TTY,这样您就不会在隔行扫描的行上得到字符。 因此,如果正在输出程序A和B,通常会得到:

program A output
program B output
program B output
program A output
program B output

这很臭,但是比

proprogrgraam m AB  ououtputputt
prproogrgram amB A  ououtputtput
program B output

请注意,甚至不能保证在换行符上进行刷新,因此,如果刷新很重要,则应显式刷新。


#6楼

使用setbuf(stdout, NULL); 禁用缓冲。


#7楼

默认情况下,stdout是行缓冲的,stderr是不缓冲的,文件是完全缓冲的。


#8楼

注意:Microsoft运行时库不支持行缓冲,因此printf("will print immediatelly to terminal")

http://msdn.microsoft.com/en-us/library/86cebhfs.aspx


#9楼

不,这不是POSIX行为,它是ISO行为(嗯,这 POSIX行为,但仅在它们符合ISO的范围内)。

如果可以检测到标准输出是指交互式设备,则标准输出将被行缓冲,否则将被完全缓冲。 因此,在某些情况下,即使有换行发送, printf也不会刷新,例如:

myprog >myfile.txt

这对于提高效率很有意义,因为如果您与用户互动,他们可能希望查看每一行。 如果将输出发送到文件,则很可能另一端没有用户(尽管并非不可能,但他们可能会拖尾文件)。 现在您可以争辩说用户希望看到每个字符,但这有两个问题。

首先是效率不是很高。 第二个原因是,最初的ANSI C指令主要是为了整理现有的行为,而不是发明新的行为,而这些设计决策是在ANSI开始该过程之前就做出的。 如今,在更改标准中的现有规则时,即使是ISO现在也要非常谨慎。

至于如何处理,如果您在要立即看到的每个输出调用之后都进行了fflush (stdout) ,则可以解决此问题。

另外,您也可以使用setvbuf在操作之前stdout ,将其设置为无缓冲,你会不会有关于添加所有这些担心fflush行到你的代码:

setvbuf (stdout, NULL, _IONBF, BUFSIZ);

只要记住这可能会影响性能相当多,如果你发送的输出到文件。 还要记住,对此的支持是实现定义的,标准并不能保证。

ISO C99第7.19.3/3节是相关的位:

当流没有缓冲时 ,字符应尽快从源或目标出现。 否则,字符可能会作为块被累积并传输到主机环境或从主机环境传输。

当流被完全缓冲时 ,打算在填充缓冲区时将字符作为块与主机环境进行传输。

当流被行缓冲时 ,当遇到换行符时 ,字符打算作为块与主机环境进行传输。

此外,当填充缓冲区,在无缓冲流上请求输入或在需要从主机环境传输字符的行缓冲流上请求输入时,打算将字符作为块传输到主机环境。 。

对这些特性的支持是实现定义的,并且可能会受到setbufsetvbuf函数的影响。


#10楼

通常有2级缓冲-

1.内核缓冲区高速缓存(使读/写速度更快)

2.在I / O库中缓冲(减少系统调用的数量)

让我们以fprintf and write()为例。

当您调用fprintf() ,它不会直接写入文件。 它首先进入程序内存中的stdio缓冲区。 使用写入系统调用从那里将其写入内核缓冲区高速缓存。 因此,跳过I / O缓冲区的一种方法是直接使用write()。 其他方式是通过使用setbuff(stream,NULL) 。 这会将缓冲模式设置为不缓冲,并且数据直接写入内核缓冲区。 为了强制将数据转移到内核缓冲区,我们可以使用“ \\ n”,在默认缓冲模式为“行缓冲”的情况下,它将刷新I / O缓冲区。 或者我们可以使用fflush(FILE *stream)

现在我们在内核缓冲区中。 内核(/ OS)希望最大程度地减少磁盘访问时间,因此它仅读/写磁盘块。 因此,当发出read()这是系统调用,可以直接调用或通过fscanf()调用时,内核将从磁盘读取磁盘块并将其存储在缓冲区中。 之后,将数据从此处复制到用户空间。

类似地,内核将从I / O缓冲区中接收到的fprintf()数据写入磁盘。 这使得read(),write()更快。

现在要强制内核启动write() ,然后由硬件控制器控制数据传输,还有一些方法。 在写调用期间,我们可以使用O_SYNC或类似的标志。 或者我们可以使用其他函数,例如fsync(),fdatasync(),sync() ,使内核缓冲区中的数据可用后立即启动写操作。

除非换行符在格式字符串中,否则为什么在调用后printf不会刷新?相关推荐

  1. qlabel设置换行符无效_php 字符串中的\n换行符无效、不能换行的解决方法

    例如下面的代码: echo 'hello\n'; echo 'world'; ?> 程序的中的换行符\n会直接输出,无法正确换行,解决方法是把单引号改为双引号: echo "hello ...

  2. 换行符javajava去除字符串中的空格、回车、换行符、制表符

    在改章节中,我们主要介绍换行符java的内容,自我感觉有个不错的建议和大家分享下 每日一道理 只有启程,才会到达理想和目的地,只有拼搏,才会获得辉煌的成功,只有播种,才会有收获.只有追求,才会品味堂堂 ...

  3. python怎么去掉换行符_python去除字符串中的换行符

    今天写这个,要用python去除字符串中的换行符并写入文件,网上查阅,就一句代码replace("\n",""),加上之后,搞了半天,还是不对. 以上是我今天遇 ...

  4. python 替换换行符,python去除字符串中的换行符

    今天写这个,要用python去除字符串中的换行符并写入文件,网上查阅,就一句代码replace("\n",""),加上之后,搞了半天,还是不对. 以上是我今天遇 ...

  5. java字符串 n换行符_java切割字符串中的回车应注意是\n\r不是\n

    我们在Java中如果用到处理要分隔字符串,不免会用到String的split(String regex)函数,这时候我们要注意的. 如果想以回车来分隔字符串,很多同学都会这样做.下面是例子: Stri ...

  6. java replace换行符_Java 替换字符串中的回车换行符的方法

    使用正则表达式进行替换: 代码片段: string documenttxt = entityutils.tostring(entity,"gbk");//获取数据 document ...

  7. excel 替换 换行符_在Excel中查找和替换换行符

    excel 替换 换行符 When you want to create a line break (line feed) in a cell, you press Alt + Enter, to s ...

  8. 怎么在php中加入换行符,如何在PHP中创建换行符?

    为了创建换行符, PHP提供了nl2br()函数.它是PHP的内置函数, 用于在字符串中的所有换行符之前插入HTML换行符.虽然, 我们也可以在源代码中使用PHP换行符\ n或\ r \ n来创建换行 ...

  9. python关键词提取_如何从Python格式字符串中提取关键字? - python

    我想在API中提供自动字符串格式,例如: my_api("path/to/{self.category}/{self.name}", ...) 可以替换为格式化字符串中标注的属性值 ...

最新文章

  1. 数据结构-Hash总结(三):实践基础篇
  2. python构建二叉树_BinaryTree:学习二叉树的Python库
  3. 美国东北大学khoury计算机学院,2021年美国东北大学计算机研究生专业有哪些?入学要求高吗?...
  4. 根据输入的日期计算周次和月份
  5. 如何请教问题且以后都会回答你的方法
  6. c# 判断是否为数组_c# – 如何检查反射类型是否为数组
  7. 别乱提交代码了,你必须知道的 Git 分支开发规范!
  8. JAVA语法基础作业——动手动脑以及课后实验性问题 (七)
  9. 初始C语言——完数问题
  10. win10计算机上的策略禁止用户安装,win10电脑安装摄像头驱动时提示策略禁止安装此设备的解决教程...
  11. (新型事件相机有关的论文解读)A Unifying Contrast Maximization Framework for Event Cameras
  12. 处理Maven本地仓库.lastUpdated文件
  13. 8.17.6. Constructing Ranges
  14. 混合整数线性规划——切割平面
  15. Automatic White Balance(AWB)/Color Constancy(CC)系列论文
  16. code epi 光场_光场相机视觉测量误差分析
  17. 探讨read的返回值的三种情况
  18. ssm+vue+elementUI 基于微信小程序的游戏美术外包管理信息系统-#毕业设计
  19. const是java的关键字_const关键字及其作用(用法),C语言const详解
  20. Spring定时器的时间表达式

热门文章

  1. 一篇比较好的介绍(两种线程模式)
  2. ATextAppearance.AppCompat.Small not found
  3. java 打破双亲委派,为什么说java spi破坏双亲委派模型?
  4. PHP学习笔记-流程控制语句
  5. Android之自定义控件一起制作自定义标签
  6. Android10.0 startActivity启动过程
  7. Explain执行计划
  8. arguments.length
  9. Java实现文件复制的四种方式
  10. 处理文本框的鼠标事件,判断鼠标的状态