【问题标题】:Capturing cout in Visual Studio 2005 output window?在 Visual Studio 2005 输出窗口中捕获 cout?
【发布时间】:2010-09-09 13:16:06
【问题描述】:

我创建了一个 C++ 控制台应用程序,并且只想在 Visual Studio 2005 IDE 的输出窗口中捕获 cout/cerr 语句。我确定这只是我缺少的设置。谁能指出我正确的方向?

【问题讨论】:

    标签: c++ visual-studio visual-c++-2005


    【解决方案1】:

    我终于实现了,所以想和大家分享一下:

    #include <vector>
    #include <iostream>
    #include <windows.h>
    #include <boost/iostreams/stream.hpp>
    #include <boost/iostreams/tee.hpp>
    
    using namespace std;
    namespace io = boost::iostreams;
    
    struct DebugSink
    {
        typedef char char_type;
        typedef io::sink_tag category;
    
        std::vector<char> _vec;
    
        std::streamsize write(const char *s, std::streamsize n)
        {
            _vec.assign(s, s+n);
            _vec.push_back(0); // we must null-terminate for WINAPI
            OutputDebugStringA(&_vec[0]);
            return n;
        }
    };
    
    int main()
    {
        typedef io::tee_device<DebugSink, std::streambuf> TeeDevice;
        TeeDevice device(DebugSink(), *cout.rdbuf());
        io::stream_buffer<TeeDevice> buf(device);
        cout.rdbuf(&buf);
    
        cout << "hello world!\n";
        cout.flush(); // you may need to flush in some circumstances
    }
    

    额外提示:如果你写:

    X:\full\file\name.txt(10) : message
    

    到输出窗口,然后双击它,Visual Studio 将跳转到给定文件的第 10 行,并在状态栏中显示“消息”。它非常很有用。

    【讨论】:

    • 这对我来说效果很好,但是对于 VS2013 和 Boost 1.57,它会在流被刷新后立即崩溃,并在 Boost 代码中出现断言失败,无论是通过打印很多还是通过发送 @ 987654323@ 到流中,所以它不再可用 :-( 不确定这是 Boost 中的错误还是什么。
    【解决方案2】:

    你可以像这样捕获cout的输出,例如:

    std::streambuf* old_rdbuf = std::cout.rdbuf();
    std::stringbuf new_rdbuf;
    // replace default output buffer with string buffer
    std::cout.rdbuf(&new_rdbuf);
    
    // write to new buffer, make sure to flush at the end
    std::cout << "hello, world" << std::endl;
    
    std::string s(new_rdbuf.str());
    // restore the default buffer before destroying the new one
    std::cout.rdbuf(old_rdbuf);
    
    // show that the data actually went somewhere
    std::cout << s.size() << ": " << s;
    

    将它添加到 Visual Studio 2005 输出窗口中作为练习留给了 Visual Studio 2005 插件开发人员。但是您可以将其重定向到其他地方,例如文件或自定义窗口,也许可以通过编写自定义 streambuf 类(另请参见 boost.iostream)。

    【讨论】:

    • 不需要插件,只需使用 Mike Dimmick 提到的 OutputDebugString。
    【解决方案3】:

    你不能这样做。

    如果要输出到调试器的输出窗口,请调用 OutputDebugString。

    我发现了一个“teestream”的this implementation,它允许一个输出进入多个流。您可以实现一个将数据发送到 OutputDebugString 的流。

    【讨论】:

      【解决方案4】:

      Ben 的答案和 Mike Dimmick 的答案相结合:您将实现一个 stream_buf_,它最终会调用 OutputDebugString。也许有人已经这样做了?看看两个提议的 Boost 日志库。

      【讨论】:

        【解决方案5】:

        这是输出屏幕只是闪烁然后消失的情况吗?如果是这样,您可以使用 cin 作为返回前的最后一条语句,使其保持打开状态。

        【讨论】:

        • 不,你不能,因为单独评估 cin 没有效果。
        【解决方案6】:

        此外,根据您的意图以及您使用的库,您可能希望使用TRACE macro (MFC) 或ATLTRACE (ATL)。

        【讨论】:

          【解决方案7】:

          写入 std::ostringsteam 然后跟踪它。

          std::ostringstream oss;
          
          oss << "w:=" << w << " u=" << u << " vt=" << vt << endl;
          
          TRACE(oss.str().data());
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多