【问题标题】:redirected cout -> std::stringstream, not seeing EOL重定向 cout -> std::stringstream,没有看到 EOL
【发布时间】:2009-12-10 15:07:19
【问题描述】:

我已经阅读了很多关于将 std::cout 重定向到字符串流的帖子,但是我在读取重定向的字符串时遇到了问题。

std::stringstream redirectStream;
std::cout.rdbuf( redirectStream.rdbuf() );

std::cout << "Hello1\n";
std::cout << "Hello2\n";

while(std::getline(redirectStream, str))
{
  // This does not work - as the contents of redirectStream 
  // do not include the '\n' - I only see "Hello1Hello2"
}

我需要在初始输出中挑选出新行 - 谁能告诉我如何做到这一点?

谢谢。

【问题讨论】:

  • 供您参考,这适用于我的机器。 (Visual C++ 2008)

标签: c++ redirect stringstream cout


【解决方案1】:

对我来说很好用:
注意: std::getline() 读取行(但不是 '\n' 字符,在读取每一行后,行终止符被丢弃)。但是每行都会进入一次循环。

#include <iostream>
#include <sstream>

int main()
{
    std::stringstream   redirectStream;
    std::streambuf*     oldbuf  = std::cout.rdbuf( redirectStream.rdbuf() );

    std::cout << "Hello1\n";
    std::cout << "Hello2\n";

    std::string str;
    while(std::getline(redirectStream, str))
    {
        fprintf(stdout,"Line: %s\n",str.c_str());
        // loop enter once for each line.
        // Note: str does not include the '\n' character.
    }

    // In real life use RAII to do this. Simplified here for code clarity.
    std::cout.rdbuf(oldbuf);
}

注意:您需要将旧的流缓冲区放回 std::cout。一旦 stringstream 'redirectStream' 超出范围,它的缓冲区将被销毁,使 std::cout 指向无效的流缓冲区。由于 std::cout 的寿命比 'redirectStream' 长,您需要确保 std::cout 不会访问无效对象。因此,最简单的解决方案是放回旧缓冲区。

【讨论】:

    【解决方案2】:

    感谢您的回复。我可以看出我做错了什么。因为我删除了很多代码来简化我的问题,是的,我确实发布了一个工作版本!看来我的实际逻辑是问题所在:

    // Basically... 
    std::string str; 
    std::stringstream redirectstream; 
    // perform the redirection... 
    // ... 
    
    while (!done)
    { 
      while(std::getline(redirectStream, str)) 
      { 
        // stuff... 
      } 
      std::cout << "Hello1\n"; 
      std::cout << "Hello2\n"; 
    } 
    

    在这种情况下,getline() 函数似乎不再有效。你能解释一下吗?

    我现在意识到这是一个完全不同的问题,对于最初发布的糟糕帖子造成的误导,我深表歉意。

    【讨论】:

    • 欢迎来到 Stack Overflow。答案部分是针对问题的答案,而不是针对其他答案的回复或后续问题。要回复答案,请使用每个答案下方的“评论”部分。 (在您自己的问题页面上发表评论时,将放弃最低声誉。)我已投票以“不再相关”结束此问题,因为您承认您发布的内容并不是真正的问题。我建议您重新开始,并根据您在此“答案”中所写的内容发布一个 问题。 (已经有了答案,所以编辑这个问题只会让事情变得混乱。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2016-09-10
    相关资源
    最近更新 更多