Як записати у вікно виводу у 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

1
Чи потрібно мені #include щось, щоб OutputDebugString запрацював?
Мікеле,

включають Windows.h
ΦXocę 웃 Пепеупа

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, щоб надати ще більше інформації."
Yousuf Azad

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
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

wstring outputMe = L"can" + L" concatenate\n";
OutputDebugString(outputMe.c_str());

#include <string>
Ендрю

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.