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