How to redirect standard output to output window from Visual Studio

后端 未结 4 1954
迷失自我
迷失自我 2020-12-14 18:19

Is it possible to redirect standard output to the output window from Visual Studio?

I use OutputDebugString in my program, but I use some libraries that

4条回答
  •  [愿得一人]
    2020-12-14 18:55

    From Redirecting cerr and clog to OutputDebugString():

    #include 
    #include 
    
    /// \brief This class is derives from basic_stringbuf which will output
    /// all the written data using the OutputDebugString function
    template>
    class OutputDebugStringBuf : public std::basic_stringbuf {
    public:
        explicit OutputDebugStringBuf() : _buffer(256) {
            setg(nullptr, nullptr, nullptr);
            setp(_buffer.data(), _buffer.data(), _buffer.data() + _buffer.size());
        }
    
        ~OutputDebugStringBuf() {
        }
    
        static_assert(std::is_same::value ||
                        std::is_same::value,
                      "OutputDebugStringBuf only supports char and wchar_t types");
    
        int sync() try {
            MessageOutputer()(pbase(), pptr());
            setp(_buffer.data(), _buffer.data(), _buffer.data() + _buffer.size());
            return 0;
        }
        catch(...) {
            return -1;
        }
    
        int_type overflow(int_type c = TTraits::eof()) {
            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 _buffer;
    
        template
        struct MessageOutputer;
    
        template<>
        struct MessageOutputer> {
            template
            void operator()(TIterator begin, TIterator end) const {
                std::string s(begin, end);
                OutputDebugStringA(s.c_str());
            }
        };
    
        template<>
        struct MessageOutputer> {
            template
            void operator()(TIterator begin, TIterator end) const {
                std::wstring s(begin, end);
                OutputDebugStringW(s.c_str());
            }
        };
    };
    

    Then:

    int main() {
        #ifndef NDEBUG
            #ifdef _WIN32
                static OutputDebugStringBuf charDebugOutput;
                std::cerr.rdbuf(&charDebugOutput);
                std::clog.rdbuf(&charDebugOutput);
    
                static OutputDebugStringBuf wcharDebugOutput;
                std::wcerr.rdbuf(&wcharDebugOutput);
                std::wclog.rdbuf(&wcharDebugOutput);
            #endif
        #endif
    
        ...
    
        // Will be displayed in the debugger
        std::cerr << "Error: something bad happened" << std::endl;
    
        ...
    }
    

    You might want to use it with

    IsDebuggerPresent()

    so that it still outputs to console when not run from the Visual Studio debugger.

提交回复
热议问题