Jak pisać w oknie danych wyjściowych w programie Visual Studio?

79

Której funkcji należy użyć do wyprowadzenia tekstu w oknie „Dane wyjściowe” w programie Visual Studio?

Próbowałem, printf()ale to się nie pojawia.

Zacisk
źródło

Odpowiedzi:

84

Zrobi to funkcja OutputDebugString .

przykładowy kod

    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);
}
Sorantis
źródło
3
Nadal jest z tym problem. _vsnprintf może obciąć sformatowany ciąg, aby dopasować go do buforu, ale jeśli tak się stanie, ciąg nie zostanie zakończony znakiem nul. Zobacz msdn.microsoft.com/en-us/library/1kt27hek.aspx i stackoverflow.com/questions/357068 .
ChrisN,
Używasz wielobajtowego zestawu znaków w opcjach kompilatora. Następnie musisz użyć wielobajtowych wersjiWCHAR szBuff[1024] _vsnwprintf
Lefteris E
Ostrzeżenie 1, ostrzeżenie C4996: „_vsnwprintf”: Ta funkcja lub zmienna może być niebezpieczna. Zamiast tego rozważ użycie _vsnwprintf_s. ;-)
hfrmobile
1
Czy muszę #include coś, aby OutputDebugString działało?
Michele
dołącz
72

Jeśli jest to dane wyjściowe do debugowania, to OutputDebugString jest tym, czego chcesz. Przydatne makro:

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

Dzięki temu możesz mówić na przykład:

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

Możesz to rozszerzyć za pomocą makr __LINE__i, __FILE__aby uzyskać jeszcze więcej informacji.

Dla osób korzystających z Windows i szerokiej krainy postaci:

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

 #define DBOUT( s )            \
{                             \
   std::wostringstream os_;    \
   os_ << s;                   \
   OutputDebugStringW( os_.str().c_str() );  \
}
Społeczność
źródło
1
Czy możesz trochę wyjaśnić to stwierdzenie? - „Można to rozszerzyć za pomocą makr LINE i FILE, aby uzyskać jeszcze więcej informacji”.
Yousuf Azad
2
@ sami1592 te dwa makra są definiowane przez kompilator jako (niespodzianka) wiersz i plik, więc możesz automatycznie wypisywać bardziej przydatne dzienniki zawierające linię i plik.
ZachB
20

Użyj OutputDebugStringfunkcji lub TRACEmakra (MFC), które pozwala na printfformatowanie w stylu:

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 );
Reunanen
źródło
Mój kompilator w programie Visual Studio nie rozpoznaje ALTTRACE2 ani ALTTRACE. Czy muszę # uwzględniać coś? Czy to dlatego, że nie jest to projekt MFC? Dla mnie to po prostu c ++.
Michele
Testowałem stary algorytm 3DES w Visual Studio 2017, C ++. Kod działał po zamianie wszystkich "printf" na "TRACE". Bardzo dobry hit! Dziękuję Ci!
Paul
3

Przydatna wskazówka - jeśli używasz, __FILE__a __LINE__następnie sformatujesz debugowanie jako:

"file(line): Your output here"

następnie po kliknięciu tego wiersza w oknie danych wyjściowych program Visual Studio przeskoczy bezpośrednio do tego wiersza kodu. Przykład:

#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)

Napisałem o tym post na blogu, więc zawsze wiedziałem, gdzie mogę to sprawdzić: https://windowscecleaner.blogspot.co.nz/2013/04/debug-output-tricks-for-visual-studio.html

pietruszka72
źródło
0

Użyj OutputDebugString zamiast afxDump.

Przykład:

#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("[...]"));
}
Maurizio TALPO
źródło
0
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

wstring outputMe = L"can" + L" concatenate\n";
OutputDebugString(outputMe.c_str());
Andrzej
źródło
#include <string>
Andrew,
0

Mimo że OutputDebugStringrzeczywiście wyświetla ciąg znaków w konsoli debugera, nie jest dokładnie tak, jak w printfprzypadku, gdy ta ostatnia może formatować argumenty przy użyciu %notacji i zmiennej liczby argumentów, coś OutputDebugStringnie działa.

Sprowadziłbym przypadek, że _RPTFNmakro, _CRT_WARNprzynajmniej z argumentami, jest w tym przypadku lepszym konkurentem - formatuje główny ciąg podobnie jak printfzapisując wynik do konsoli debuggera.

A minor (i dziwne, moim zdaniem) zastrzeżenie z nim jest to, że wymaga co najmniej jeden argument następujący ciąg formatu (ten z całą %substytucji), ograniczenie printfczy nie cierpią.

W przypadkach, w których potrzebujesz putspodobnej funkcjonalności - bez formatowania, po prostu pisz ciąg taki, jaki jest - istnieje jego siostra _RPTF0(która ignoruje argumenty następujące po ciągu formatu, kolejne dziwne zastrzeżenie). Lub OutputDebugStringoczywiście.

A tak przy okazji, jest też wszystko od _RPT1do, _RPT5ale ich nie próbowałem. Szczerze mówiąc, nie rozumiem, dlaczego zapewniam tak wiele procedur, które zasadniczo robią to samo.

amn
źródło