【问题标题】:Visual Studio 2012 - Embedded output console instead of cmd?Visual Studio 2012 - 嵌入式输出控制台而不是 cmd?
【发布时间】:2014-05-23 01:31:40
【问题描述】:

是否可以将嵌入式输出控制台作为 VS2012 窗口的一部分,而不是在运行时打开 cmd?

例如,在 Eclipse 中,输出默认定向到“控制台”窗格,如果可用的话,我想在 VS2012 中实现类似的功能。

【问题讨论】:

标签: c++ visual-studio-2012 cmd console output


【解决方案1】:

以下是执行此操作所涉及的代码的完整示例:

http://blog.tomaka17.com/2011/07/redirecting-cerr-and-clog-to-outputdebugstring/

基本上,作者创建了一个新的std::basic_stringbuf,它使用MSVC 函数OutputDebugString(),并通过std::cerr.rdbuf(&newStreamBuf) 将其绑定到clogcerr。这也适用于cout

我实际上编译了他的代码并遇到了一些问题,这里是更正的版本:

cpp 文件:

// redirectStreamBuf.cpp

//Feel free to modify target options here (for example #ifndef NDEBUG)
#ifdef _WIN32
    #define ENABLE_MSVC_OUTPUT
#endif


#include <iostream>
#include <vector>
#include <sstream>

#ifdef ENABLE_MSVC_OUTPUT
#include <Windows.h>
#endif


#ifdef ENABLE_MSVC_OUTPUT
template<typename TChar, typename TTraits = std::char_traits<TChar>>
class OutputDebugStringBuf : public std::basic_stringbuf<TChar,TTraits> {
public:
    typedef std::basic_stringbuf<TChar, TTraits> BaseClass;

    explicit OutputDebugStringBuf() : _buffer(256) {
        setg(nullptr, nullptr, nullptr);
        setp(_buffer.data(), _buffer.data(), _buffer.data() + _buffer.size());
    }

    static_assert(std::is_same<TChar,char>::value || std::is_same<TChar,wchar_t>::value, "OutputDebugStringBuf only supports char and wchar_t types");

    int sync() override try {
        MessageOutputer<TChar,TTraits>()(pbase(), pptr());
        setp(_buffer.data(), _buffer.data(), _buffer.data() + _buffer.size());
        return 0;
    } catch(...) {
        return -1;
    }

    typename BaseClass::int_type overflow(typename BaseClass::int_type c = TTraits::eof()) override {
        auto syncRet = sync();
        if (c != TTraits::eof()) {
            _buffer[0] = c;
            setp(_buffer.data(), _buffer.data() + 1, _buffer.data() + _buffer.size());
        }
        return syncRet == -1 ? TTraits::eof() : 0;
    }


private:
    std::vector<TChar> _buffer;

    template<typename TChar, typename TTraits>
    struct MessageOutputer;

    template<>
    struct MessageOutputer<char, std::char_traits<char>> {
        template<typename TIterator>
        void operator()(TIterator begin, TIterator end) const {
            std::string s(begin, end);
            OutputDebugStringA(s.c_str());
        }
    };

    template<>
    struct MessageOutputer<wchar_t, std::char_traits<wchar_t>> {
        template<typename TIterator>
        void operator()(TIterator begin, TIterator end) const {
            std::wstring s(begin, end);
            OutputDebugStringW(s.c_str());
        }
    };
};
#endif


void RedirectStdoutToMSVC()
{
#ifdef ENABLE_MSVC_OUTPUT
    static OutputDebugStringBuf<char> outputDebugBufChar;
    static OutputDebugStringBuf<wchar_t> outputDebugBufWChar;

    std::cout.rdbuf(&outputDebugBufChar);
    std::cerr.rdbuf(&outputDebugBufChar);
    std::clog.rdbuf(&outputDebugBufChar);

    std::wcout.rdbuf(&outputDebugBufWChar);
    std::wcerr.rdbuf(&outputDebugBufWChar);
    std::wclog.rdbuf(&outputDebugBufWChar);
#endif
}

头文件:

// redirectStreamBuf.h
#ifndef REDIRECT_STREAM_BUF_H__
#define REDIRECT_STREAM_BUF_H__
void RedirectStdoutToMSVC();
#endif

下面是一些测试用例的用法:

#include "redirectStreamBuf.h"
#include <iostream>


int main(char *argv, int argc)
{
    RedirectStdoutToMSVC();

    std::cout << "Test cout" << std::endl;
    std::cerr << "Test cerr" << std::endl;
    std::clog << "Test clog" << std::endl;
    std::wcout << L"Test wcout" << std::endl;
    std::wcerr << L"Test wcerr" << std::endl;
    std::wclog << L"Test wclog" << std::endl;

    printf("This will not work :( \n");

    system("PAUSE"); //Yes I know...
    return 0;
}

我用 Visual Studio 2012 测试了所有这些,它运行良好。像 printf 这样的 C 样式函数虽然不起作用...

【讨论】:

    【解决方案2】:

    创建调试输出函数是个好主意,然后您可以根据需要对其进行修改以将输出重定向到需要的位置。请记住,尽管与控制台相比,Windows 中的文本框非常非常慢,甚至控制台也没有那么快。

    如果您有大量调试输出,则会对您的应用程序产生显着影响。例如,我正在使用嵌入式设备进行一些通信并将原始数据吐出到调试窗口。提取我需要的数据大约需要 4 分钟。我将调试输出切换到真正的控制台窗口,大约需要 20 秒。

    这些天我只是使用 AllocConsole() 打开一个真正的控制台窗口。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-24
      • 1970-01-01
      • 2013-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多