Как писать в окно вывода в Visual Studio?


79

Какую функцию следует использовать для вывода текста в окно «Вывод» в Visual Studio?

Я пробовал, printf()но ничего не получается.

Ответы:


84

Функция OutputDebugString сделает это.

пример кода

    void CClass::Output(const char* szFormat, ...)
{
    char szBuff[1024];
    va_list arg;
    va_start(arg, szFormat);
    _vsnprintf(szBuff, sizeof(szBuff), szFormat, arg);
    va_end(arg);

    OutputDebugString(szBuff);
}

3
С этим все еще есть проблема. _vsnprintf может обрезать отформатированную строку до размера буфера, но если это произойдет, строка не будет завершаться нулем. См. Msdn.microsoft.com/en-us/library/1kt27hek.aspx и stackoverflow.com/questions/357068 .
ChrisN

Вы используете многобайтовый набор символов в параметрах компилятора. Затем вам необходимо использовать многобайтовые версииWCHAR szBuff[1024] _vsnwprintf
Lefteris E

Предупреждение 1 предупреждение C4996: '_vsnwprintf': эта функция или переменная может быть небезопасной. Вместо этого рассмотрите возможность использования _vsnwprintf_s. ;-)
hfrmobile 03

1
Мне нужно что-то #include, чтобы заставить OutputDebugString работать?
Мишель

включают Windows.h
ΦXocę 웃 Пepeúpa ツ

72

Если это для вывода отладки, то OutputDebugString - это то, что вам нужно. Полезный макрос:

#define DBOUT( s )            \
{                             \
   std::ostringstream os_;    \
   os_ << s;                   \
   OutputDebugString( os_.str().c_str() );  \
}

Это позволяет вам говорить такие вещи, как:

DBOUT( "The value of x is " << x );

Вы можете расширить это с помощью __LINE__и __FILE__макросы , чтобы дать еще больше информации.

Для тех, кто пользуется Windows и широким характером:

#include <Windows.h>
#include <iostream>
#include <sstream>

 #define DBOUT( s )            \
{                             \
   std::wostringstream os_;    \
   os_ << s;                   \
   OutputDebugStringW( os_.str().c_str() );  \
}

1
Вы можете немного пояснить это утверждение? - «Вы можете расширить это, используя макросы LINE и FILE, чтобы предоставить еще больше информации».
Юсуф Азад,

2
@ sami1592 эти два макроса определены компилятором как (неожиданная) строка и файл, поэтому вы можете автоматически выводить более полезные журналы, содержащие строку и файл.
ZachB

20

Используйте OutputDebugStringфункцию или TRACEмакрос (MFC), который позволяет выполнять printfформатирование в стиле:

int x = 1;
int y = 16;
float z = 32.0;
TRACE( "This is a TRACE statement\n" );    
TRACE( "The value of x is %d\n", x );
TRACE( "x = %d and y = %d\n", x, y );
TRACE( "x = %d and y = %x and z = %f\n", x, y, z );

Мой компилятор в Visual Studio не распознает ALTTRACE2 или ALTTRACE. Мне нужно что-то # включить? Это потому, что это не проект MFC? Для меня это просто C ++.
Мишель

Я тестировал старый алгоритм 3DES в Visual Studio 2017, C ++. Я заставил код работать, заменив все "printf" на "TRACE". Очень хороший хит! Спасибо!
Пол

3

Полезный совет - если вы используете, __FILE__а __LINE__затем форматируете отладку как:

"file(line): Your output here"

затем, когда вы щелкнете по этой строке в окне вывода, Visual Studio перейдет непосредственно к этой строке кода. Пример:

#include <Windows.h>
#include <iostream>
#include <sstream>

void DBOut(const char *file, const int line, const WCHAR *s)
{
    std::wostringstream os_;
    os_ << file << "(" << line << "): ";
    os_ << s;
    OutputDebugStringW(os_.str().c_str());
}

#define DBOUT(s)       DBOut(__FILE__, __LINE__, s)

Я написал об этом сообщение в блоге, поэтому всегда знал, где его найти: https://windowscecleaner.blogspot.co.nz/2013/04/debug-output-tricks-for-visual-studio.html


0

Используйте OutputDebugString вместо afxDump.

Пример:

#define _TRACE_MAXLEN 500

#if _MSC_VER >= 1900
#define _PRINT_DEBUG_STRING(text) OutputDebugString(text)
#else // _MSC_VER >= 1900
#define _PRINT_DEBUG_STRING(text) afxDump << text
#endif // _MSC_VER >= 1900

void MyTrace(LPCTSTR sFormat, ...)
{
    TCHAR text[_TRACE_MAXLEN + 1];
    memset(text, 0, _TRACE_MAXLEN + 1);
    va_list args;
    va_start(args, sFormat);
    int n = _vsntprintf(text, _TRACE_MAXLEN, sFormat, args);
    va_end(args);
    _PRINT_DEBUG_STRING(text);
    if(n <= 0)
        _PRINT_DEBUG_STRING(_T("[...]"));
}


0

Несмотря на то, что OutputDebugStringдействительно выводит строку символов в консоль отладчика, это не совсем то, printfчто последняя может форматировать аргументы, используя %нотацию и переменное количество аргументов, что-тоOutputDebugString не происходит.

Я бы сказал, что _RPTFNмакрос, _CRT_WARNпо крайней мере с аргументом, в этом случае лучше подходит - он форматирует основную строку так же, как printfзапись результата в консоль отладчика.

Незначительная (и странно, на мой взгляд) предостережение с ним в том , что он требует , по крайней мере один аргумент следующий в строке формата (тот , со всеми %для замещения), ограничение printfделает не страдает от.

Для случаев, когда вам нужна putsподобная функциональность - без форматирования, просто запись строки как есть - есть ее родственник _RPTF0(который игнорирует аргументы, следующие за строкой формата, еще одно странное предостережение). Или жеOutputDebugString конечно.

И, кстати, тоже есть все от _RPT1до, _RPT5но я не пробовал. Честно говоря, я не понимаю, зачем предлагать столько процедур, которые по сути делают одно и то же.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.