Mam projekt win32, który załadowałem do programu Visual Studio 2005. Chciałbym móc drukować rzeczy do okna wyjściowego programu Visual Studio, ale do końca życia nie mogę się tego dowiedzieć. Próbowałem „printf” i „cout <<”, ale moje wiadomości uparcie pozostają niewydrukowane.
Czy istnieje jakiś specjalny sposób drukowania w oknie wyjściowym programu Visual Studio?
Odpowiedzi:
Możesz użyć
OutputDebugString
.OutputDebugString
to makro, które w zależności od opcji kompilacji jest mapowane naOutputDebugStringA(char const*)
lubOutputDebugStringW(wchar_t const*)
. W późniejszym przypadku będziesz musiał dostarczyć do funkcji szeroki ciąg znaków. Aby utworzyć literał szerokiego znaku, możesz użyćL
przedrostka:OutputDebugStringW(L"My output string.");
Zwykle będziesz używać wersji makra razem z
_T
makrem w następujący sposób:OutputDebugString(_T("My output string."));
Jeśli projekt jest skonfigurowany do kompilowania dla UNICODE, rozwinie się do:
OutputDebugStringW(L"My output string.");
Jeśli nie tworzysz dla UNICODE, rozwinie się do:
OutputDebugStringA("My output string.");
źródło
myStr
. Jest tochar*
,wchar_t*
czyLPTSTR
? Zakładając, że jest tochar*
po prostu zadzwonićOutputDebugStringA(myStr)
lub skorzystaćOutputDebugStringW
zwchar_t*
iOutputDebugString
zLPTSTR
jak wyjaśniono w mojej odpowiedzi.OutputDebugString
i albo zdefiniuj odpowiednie symbole preprocesora, aby pasowały do szerokości używanych znaków, albo wybierz elastyczne typy „T”, które pozwalają na kompilację do znaków 8- i 16-bitowych.Jeśli projekt jest projektem GUI, konsola nie pojawi się. Aby zamienić projekt na konsolowy należy wejść do panelu właściwości projektu i ustawić:
To rozwiązanie działa tylko wtedy, gdy masz klasyczną metodę „ int main () punkt wejścia ”.
Ale jeśli jesteś taki jak w moim przypadku (projekt openGL), nie musisz edytować właściwości, ponieważ działa to lepiej:
AllocConsole(); freopen("CONIN$", "r",stdin); freopen("CONOUT$", "w",stdout); freopen("CONOUT$", "w",stderr);
printf i cout będą działać jak zwykle.
Jeśli wywołasz AllocConsole przed utworzeniem okna, konsola pojawi się za oknem, jeśli wywołasz ją później, pojawi się przed.
Aktualizacja
freopen
jest przestarzały i może być niebezpieczny. Użyjfreopen_s
zamiast tego:FILE* fp; AllocConsole(); freopen_s(&fp, "CONIN$", "r", stdin); freopen_s(&fp, "CONOUT$", "w", stdout); freopen_s(&fp, "CONOUT$", "w", stderr);
źródło
EDITBIN
można ustawić podsystem na,CONSOLE
nawet jeśli używaszWinMain
zamiastint main()
.Aby drukować na
real
konsolę, musisz uczynić ją widoczną za pomocą flagi konsolidatora/SUBSYSTEM:CONSOLE
. Dodatkowe okno konsoli jest denerwujące, ale do celów debugowania jest bardzo cenne.OutputDebugString
drukuje na wyjściu debugera podczas uruchamiania wewnątrz debugera.źródło
Rozważ użycie makr środowiska wykonawczego VC ++ do raportowania _RPT N () i _RPTF N ()
Przykład...
if (someVar > MAX_SOMEVAR) { _RPTF2(_CRT_WARN, "In NameOfThisFunc( )," " someVar= %d, otherVar= %d\n", someVar, otherVar ); }
Lub możesz bezpośrednio użyć funkcji wykonawczych VC ++ _CrtDbgReport, _CrtDbgReportW .
źródło
_RPTF0
można jej użyć, gdy nie oczekuje się przekazywania zmiennych po ciągu formatu. Z_RPTFN
drugiej strony makro wymaga co najmniej jednego argumentu po ciągu formatu.Jeśli chcesz wydrukować zmienne dziesiętne:
wchar_t text_buffer[20] = { 0 }; //temporary buffer swprintf(text_buffer, _countof(text_buffer), L"%d", your.variable); // convert OutputDebugString(text_buffer); // print
źródło
%u
dla unsigned,%f
dla float zgodnie z odniesieniem .Jeśli chcesz zobaczyć wyjście istniejącego programu, który szeroko używał printf bez zmiany kodu (lub z minimalnymi zmianami), możesz przedefiniować printf w następujący sposób i dodać go do wspólnego nagłówka (stdafx.h).
int print_log(const char* format, ...) { static char s_printf_buf[1024]; va_list args; va_start(args, format); _vsnprintf(s_printf_buf, sizeof(s_printf_buf), format, args); va_end(args); OutputDebugStringA(s_printf_buf); return 0; } #define printf(format, ...) \ print_log(format, __VA_ARGS__)
źródło
Twój projekt Win32 jest prawdopodobnie projektem GUI, a nie projektem konsoli. Powoduje to różnicę w nagłówku pliku wykonywalnego. W rezultacie projekt GUI będzie odpowiedzialny za otwarcie własnego okna. Może to być jednak okno konsoli. Wywołaj,
AllocConsole()
aby go utworzyć, i użyj funkcji konsoli Win32, aby go zapisać.źródło
Sam szukałem sposobu, aby to zrobić i znalazłem proste rozwiązanie.
Zakładam, że uruchomiłeś domyślny projekt Win32 (aplikacja Windows) w programie Visual Studio, który udostępnia funkcję „WinMain”. Domyślnie program Visual Studio ustawia punkt wejścia na „PODSYSTEM: WINDOWS”. Najpierw musisz to zmienić, przechodząc do:
Projekt -> Właściwości -> Konsolidator -> System -> Podsystem
I wybierz „Konsola (/ SUBSYSTEM: CONSOLE)” z listy rozwijanej.
Teraz program nie będzie działać, ponieważ zamiast funkcji „WinMain” potrzebna jest funkcja „główna”.
Teraz możesz dodać funkcję „główną”, tak jak zwykle w C ++. Następnie, aby uruchomić program GUI, możesz wywołać funkcję „WinMain” z wnętrza funkcji „main”.
Początkowa część twojego programu powinna teraz wyglądać mniej więcej tak:
#include <iostream> using namespace std; // Main function for the console int main(){ // Calling the wWinMain function to start the GUI program // Parameters: // GetModuleHandle(NULL) - To get a handle to the current instance // NULL - Previous instance is not needed // NULL - Command line parameters are not needed // 1 - To show the window normally wWinMain(GetModuleHandle(NULL), NULL,NULL, 1); system("pause"); return 0; } // Function for entry into GUI program int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { // This will display "Hello World" in the console as soon as the GUI begins. cout << "Hello World" << endl; . . .
Wynik mojej realizacji
Teraz możesz używać funkcji do wyświetlania na konsoli w dowolnej części programu GUI w celu debugowania lub do innych celów.
źródło
Możesz także użyć metody WriteConsole do drukowania na konsoli.
AllocConsole(); LPSTR lpBuff = "Hello Win32 API"; DWORD dwSize = 0; WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), lpBuff, lstrlen(lpBuff), &dwSize, NULL);
źródło