【问题标题】:Calls to flush cout are ineffective调用 flush cout 无效
【发布时间】:2013-10-20 22:57:36
【问题描述】:

我试图在操作字符串之前刷新 cout 缓冲区以查看字符串。我试图通过调用std::flush()std::cout.flush() 来刷新缓冲区,但实际上都没有刷新我的输出。

只有对std::endl 的调用为我成功刷新了缓冲区。

这是我的代码

std::istringstream stm (game.date());
int day, month, year;
char delim = '/';

std::cout << "Date before: " << game.date() << std::flush; // first flush attempt
std::cout.flush();  // second flush attempt doesnt work
//std::cout << std::endl;   // if this is executed the buffer will flush

// Split date string into integers for comparison
stm >> month >> delim;
stm >> day >> delim;
stm >> year >> delim;

std::cout << "Date after: " << " | " << month << "/" << day << "/" << year << std::endl;

这是我的输出
之后的日期:| 2013 年 1 月 31 日
之后的日期:| 2012 年 3 月 21 日
之后的日期:| 2011 年 11 月 11 日
之后的日期:| 2010 年 10 月 1 日
之后的日期:| 2012 年 1 月 2 日

所以你可以看到第一次调用 cout 并没有刷新,但正如我之前所说的那样,缓冲区将成功地用 endl 刷新,它调用了 flush 本身。我目前在运行 Mountain Lion 的主机 macbook pro 上运行带有 VirtualBox 的 Ubuntu 12.04。

在我的刷新调用中我可能做错了什么还是这可能是系统问题?

【问题讨论】:

标签: c++ cout flush


【解决方案1】:

std::cout &lt;&lt; flush;std::cout.flush(); 都将刷新 std::cout

您的代码看起来好像在流中插入了一个回车符 (\r)。假设您今年打印,似乎您将其插入为char,其值为13,恰好是\r。这样做的结果是您以后的输出将覆盖输出,因为它将在同一行上。您可以通过在刷新流之前显式插入换行符 (\n) 来验证这一点。

【讨论】:

  • 呃。 \n 不会在大多数系统上导致 stdout 刷新吗?
  • @sehe:很遗憾,它可能会这样做,因为大多数 IOStreams 实现选择缓慢并委托给&lt;stdio&gt; 例程。由于大多数程序也不调用std::ios_base::sync_with_stdio(false)(如果它们不将&lt;stdio&gt; 与标准流上的&lt;iostream&gt; 操作混合使用,它们应该调用),它会将每个字符写入stdout。但是,实现可以做得更好,在这种情况下它可能不会在 \n 上刷新。
  • 谢谢您的回答。我将日期的 substr 从 0 变为 (length-1) 并删除了回车符。我还做了一个find 来验证它是一个'\r' 字符,确实是这样。
【解决方案2】:

cout 上有一个系统缓冲区,它仍然会在现代 Linux 系统中缓冲您的输出。

要禁用它以运行您的程序,请使用命令stdbuf,如下所示:

stdbuf -o 0 ./yourprogram --yourparams

如果您需要在调试器中禁用缓冲,请像这样使用它:

stdbuf -o 0 gdb --args ./yourprogram --yourparams

【讨论】:

    【解决方案3】:

    Flush 仅将流的缓冲区写入实际设备(文件或 tty)。

    如果这是您所期望的,它不会移动到下一行。

    这是设计使然。

    请注意,这里有一个更简洁的代码版本,它似乎可以像宣传的那样工作(不管有没有刷新):

    Live on Coliru

    #include <sstream>
    #include <iostream>
    #include <vector>
    #include <cassert>
    
    struct Game { 
        std::string _date;
        std::string date() const { return _date; }
    };
    
    int main()
    {
        for (Game game : std::vector<Game> { {"01/02/1999"}, {"24/10/2013"}})
        {
            std::istringstream stm (game.date());
            int day, month, year;
            char delim = '/';
    
            std::cout << "Date before: " << game.date();
    
            stm >> month >> delim;
            assert(stm && '/' == delim);
    
            stm >> day >> delim;
            assert(stm && '/' == delim);
    
            stm >> year;
    
            std::cout << " Date after: " << " | " << month << "/" << day << "/" << year << std::endl;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-15
      • 2015-10-06
      相关资源
      最近更新 更多