• 关于VC++输出缓冲区的一小点随笔


    【题外话】

    这是2011年底写的一篇文章,原来没有博客所以就发在了别处,现在在转到这里来,希望能对初学VC++的同学有所帮助,尤其是用VC++ 6.0练习的同学。

    【文章索引】

    1. 好长的印子
    2. 发现问题
    3. 后续

    【一、好长的引子】

    今晚有一同学问我说,说system("pause")不好用了(见图1),即出现按“请按任意键继续...”(即使用system("pause")的结果)后才会出现程序最后的运行结果(即兔子可能藏身于。。。的那两行)。我一开始并不奇怪,只是以为程序写错了,就随口说了句。


    (图1)

    结果当他把代码发过来的时候我确实没找到问题所在,而且system("pause")一行确实在cout之后。于是索性打开了VS2008,把他代码复制进去,由于他本身用的老式的C++库(VS2008不支持),所以我随手把引用都改成新式的了(图2、图3)。
    (图2)->(图3)

    然后F5运行,竟然一点问题没有(图4)。


    (图4)

    然后我又随口说了句没问题啊。不过觉得这个事不会这么简单,然后打开了VC++6.0,把他发过来的代码复制进去,结果确实如他发给我的图一样。然后我又把我改过的代码复制到VC++6.0中,结果又跟VS2008里一样没有任何问题。

    【二、发现问题】

    1、问题何在

    百度了一下这个问题,csdn上有人说在cout后加endl就可以解决。回到程序后我还真发现程序没有输出的那部分确实没有加endl,同时我突然想起是不是跟缓冲区有关,虽然我原来知道cout是把字符先放到缓冲区,但是不知道其运作模式。

    2、缓冲区的问题

    于是按上述思路百度了下VC++如何强制输出缓冲区,发现cout<<flush可以强制把缓冲区中已存的内容输出出来。于是在system("pause")之前加上了这句话,跟想象的一样——成功了。

    3、微软的问题

    问题找出来了,可是为什么引用<iostream>可以而引用<iostream.h>不可以呢,于是继续查资料,发现这确实是VC++的问题(见图5)。原文在微软知识库中:http://support.microsoft.com/kb/94227/EN-US/

    (图5)

    "在用微软C/C++开发的程序中,用cout输出的流是被缓冲的。换言之,信息送到cout流后并没有立即出现在屏幕中,而是等缓冲区清空了才显示。在VC++4.2及之后的版本中,这种情况只会发生在使用老式的iostream库。"

    好吧,微软直接说了,这种情况只会发生在使用老式的iostream的库,那也就是通过<iostream.h>调用的了。到此这个问题也就彻底明了了。

    【三、后续】

    1、针对老式的iostream.h库,微软提供的四种解决方法:

    (1)cout<<...<<endl;

    (2)cout.flush();

    (3)cout<<...<<flush;

    (4)退出程序的时候会清空当前使用的所有缓冲区。

    最后一条真是坑爹啊,当然这也就解释了,为什么程序执行了最后一条system("pause")后才把之前输出的内容输出出来。

    2、建议大家还是用标准C++的类库,也就是不要使用带“.h”的库,C++标准已经明确指出不再支持老式的类库了。其实在之后的VC++版本中也不再支持老式的库了,所以使用VC++ 6.0的同学如果还在这样写建议尽早改过来。

    3、使用标准C++类库的时候,不要忘记引用标准命名空间,即在引用类库后写一句“using namespace std;”,当然你也可以写cout时。


    如果您觉得本文对您有所帮助,不妨点击下方的“推荐”按钮来支持我!

    本文及文章中代码均基于“署名-非商业性使用-相同方式共享 3.0”,文章欢迎转载,但请您务必注明文章的作者和出处链接,如有疑问请私信我联系!

  • 相关阅读:
    PHP 数据类型
    PHP SAPI
    PHP 基础架构
    PHP7的变化
    mysql 选择优化的数据类型需要注意的几点
    彻底删除在github上提交的文件
    php7 新特性
    php缓冲区 一些笔记
    设计模式 一些概念
    mysql性能优化其中一部分小结
  • 原文地址:https://www.cnblogs.com/mayswind/p/2962047.html
Copyright © 2020-2023  润新知