У меня есть подкласс на основе ostream, который фиксирует отладочные сообщения моей программы.
/** @brief Customized output stream with "tee" feature */
template <typename CharT, typename Traits = std::char_traits<CharT> >
class basic_tostream : public std::basic_ostream<CharT, Traits> {
public:
basic_tostream(std::basic_ostream<CharT, Traits> & o1, /**< main ostream */
std::basic_ostream<CharT, Traits> & o2 /**< teed ostream */)
: std::basic_ostream<CharT, Traits>(&tbuf), tbuf(o1.rdbuf(), o2.rdbuf())
{ /* empty */ }
private:
tee_outbuf<CharT, Traits> tbuf;
}; // end_class: basic_tostream
Как я использую этот класс:
std::ofstream debugFile("debug.txt")
tostream tout(std::cout, debugFile);
/* computation */
tout << "message\n";
/* other computation */
Выпуск: Класс работает нормально, когда приложение выходит нормально. Но в случае сбоя (например, индекса массива вне границ и т. Д.) «Tout» распечатал все сообщения на консоль, но «debugFile» не захватил все распечатки.
Вопрос: Итак, как правильно очистить буфер вывода в выходной файл в случае сбоя приложения?
Одним из способов является использование обработчика сбоев. В окнах это в виде dbghlp.dll
и подсистема отладки точно в срок.
Но, безусловно, самый простой способ — очистить каждое сообщение одним из двух способов:
flush
после каждого сообщения.Я считаю, что с помощью endl
вместо "\n"
будет неявно сбрасывать.
Я рад ответить на ваш вопрос. Однажды я встретил эту проблему. Я предлагаю вам использовать dbghelp.dll.
Вы можете искать что-то о dbghelp.dll. Это очень полезно.
Вот несколько примеров:
Во-первых, вы можете написать функцию для обработки исключения.
std::ostream& operator << ( std::ostream& os, const EXCEPTION_RECORD& red )
{
// Write your error handlding code here!!!
}
Во-вторых, создайте фильтр исключений.
Вы также можете создать файл дампа здесь.
LONG __stdcall MyUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
{
std::cerr << " Unknown Error: " << (*pExceptionInfo->ExceptionRecord ) << std::endl;
exit( pExceptionInfo->ExceptionRecord->ExceptionCode );
return EXCEPTION_EXECUTE_HANDLER;
}
Затем вызовите функцию SetUnhandledExceptionFilter, чтобы установить фильтр исключений. Вы должны вызвать эту функцию до того, как произойдет исключение.
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
Иногда вы можете использовать __try и __catch.
Например:
__try
{
// Which code may cause the exception, put them here!!!
} __except( EXCEPTION_EXECUTE_HANDLER )
{
// Handle exception or write you log file here. I think it's a good idea.
}
Это все. Хороший день, чувак.