2008-10-10 9 views

Odpowiedz

0

Ponieważ nie ma okna konsoli, jest to trudne niemożliwe . (Dowiedz się czegoś nowego każdego dnia - nigdy nie wiedziałem o funkcjach konsoli!)

Czy można zastąpić połączenia wyjściowe? Często używam TRACE lub OutputDebugString do wysyłania informacji do okna wyjściowego Visual Studio.

+2

W rzeczywistości, możliwe jest, ale trudne, uzyskanie okna konsoli dla programów używających punktu wejścia WinMain() zamiast głównego(). –

+0

@ChrisCharabaruk: Wywołanie funkcji [AllocConsole] nie jest trudne (https://msdn.microsoft.com/en-us/library/windows/desktop/ms681944.aspx). Zostało to wyjaśnione w [tworzeniu konsoli] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms682528.aspx). Poza tym nazwa podanego przez użytkownika punktu wejścia nie kontroluje tworzenia konsoli. Jest to pozycja nagłówka PE dla podsystemu, który wykonuje ('WINDOWS' vs.' CONSOLE'). Visual Studio używa tego ustawienia linkera do kontrolowania, który użytkownik dostarcza punkt wejścia do wywołań kodu CRT. – IInspectable

2

Nie cytuj mnie na ten temat, ale Win32 console API może być tym, czego szukasz. Jeśli robisz to tylko w celu debugowania, możesz być bardziej zainteresowany uruchomieniem DebugView i wywoływaniem funkcji DbgPrint.

To oczywiście zakłada, że ​​aplikacja ma wysyłać dane wyjściowe konsoli, nie czytając jej z innej aplikacji. W takim przypadku fajki mogą być twoimi przyjaciółmi.

+0

Zgodnie z linkiem do 'DbgPrint', oznacza to, że' Tylko sterowniki trybu jądra mogą wywoływać procedurę DbgPrint. ". Więc pewnie nie to, co większość ludzi chce – Paladin

+0

Huh. Wiem, że istnieje funkcja trybu użytkownika do rejestrowania wiadomości, które pojawią się w DebugView. Myślałem, że to DbgPrint, ale oczywiście nie. –

+0

Funkcja trybu użytkownika do zrzucania tekstu wyświetlanego w widoku DebugView to [OutputDebugString] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa363362.aspx). – IInspectable

19

Sprawdź Adding Console I/O to a Win32 GUI App. To może pomóc ci zrobić to, co chcesz.

Jeśli nie masz lub nie możesz zmodyfikować kodu, wypróbuj sugestie znalezione here, aby przekierować wyjście konsoli do pliku.


Edit: nieco nici nekromancji tutaj. Po raz pierwszy odpowiedziałem na to pytanie 9 lat temu, na początku SO, zanim weszła w życie (dobra) polityka niezwiązanych z linkiem odpowiedzi. Prześlę kod z oryginalnego artykułu, aby odkupić moje przeszłe grzechy.

guicon.cpp - funkcja przekierowania konsoli

#include <windows.h> 
#include <stdio.h> 
#include <fcntl.h> 
#include <io.h> 
#include <iostream> 
#include <fstream> 
#ifndef _USE_OLD_IOSTREAMS 
using namespace std; 
#endif 
// maximum mumber of lines the output console should have 
static const WORD MAX_CONSOLE_LINES = 500; 
#ifdef _DEBUG 
void RedirectIOToConsole() 
{ 
    int hConHandle; 
    long lStdHandle; 
    CONSOLE_SCREEN_BUFFER_INFO coninfo; 
    FILE *fp; 

    // allocate a console for this app 
    AllocConsole(); 

    // set the screen buffer to be big enough to let us scroll text 
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo); 
    coninfo.dwSize.Y = MAX_CONSOLE_LINES; 
    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize); 

    // redirect unbuffered STDOUT to the console 
    lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE); 
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); 
    fp = _fdopen(hConHandle, "w"); 
    *stdout = *fp; 
    setvbuf(stdout, NULL, _IONBF, 0); 

    // redirect unbuffered STDIN to the console 
    lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE); 
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); 
    fp = _fdopen(hConHandle, "r"); 
    *stdin = *fp; 
    setvbuf(stdin, NULL, _IONBF, 0); 

    // redirect unbuffered STDERR to the console 
    lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE); 
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); 
    fp = _fdopen(hConHandle, "w"); 
    *stderr = *fp; 
    setvbuf(stderr, NULL, _IONBF, 0); 

    // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog 
    // point to console as well 
    ios::sync_with_stdio(); 
} 

#endif 
//End of File 

guicon.h - Interfejs do konsoli funkcję przekierowania

#ifndef __GUICON_H__ 
#define __GUICON_H__ 
#ifdef _DEBUG 

void RedirectIOToConsole(); 

#endif 
#endif 

// End of File 

test.cpp - Wykazanie przekierowanie konsoli

#include <windows.h> 
#include <iostream> 
#include <fstream> 
#include <conio.h> 
#include <stdio.h> 
#ifndef _USE_OLD_OSTREAMS 
using namespace std; 
#endif 
#include "guicon.h" 


#include <crtdbg.h> 

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) 
{ 
    #ifdef _DEBUG 
    RedirectIOToConsole(); 
    #endif 
    int iVar; 

    // test stdio 
    fprintf(stdout, "Test output to stdout\n"); 
    fprintf(stderr, "Test output to stderr\n"); 
    fprintf(stdout, "Enter an integer to test stdin: "); 
    scanf("%d", &iVar); 
    printf("You entered %d\n", iVar); 

    //test iostreams 
    cout << "Test output to cout" << endl; 
    cerr << "Test output to cerr" << endl; 
    clog << "Test output to clog" << endl; 
    cout << "Enter an integer to test cin: "; 
    cin >> iVar; 
    cout << "You entered " << iVar << endl; 
    #ifndef _USE_OLD_IOSTREAMS 

    // test wide iostreams 
    wcout << L"Test output to wcout" << endl; 
    wcerr << L"Test output to wcerr" << endl; 
    wclog << L"Test output to wclog" << endl; 
    wcout << L"Enter an integer to test wcin: "; 
    wcin >> iVar; 
    wcout << L"You entered " << iVar << endl; 
    #endif 

    // test CrtDbg output 
    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); 
    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); 
    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); 
    _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); 
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); 
    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); 
    _RPT0(_CRT_WARN, "This is testing _CRT_WARN output\n"); 
    _RPT0(_CRT_ERROR, "This is testing _CRT_ERROR output\n"); 
    _ASSERT(0 && "testing _ASSERT"); 
    _ASSERTE(0 && "testing _ASSERTE"); 
    Sleep(2000); 
    return 0; 
} 

//End of File 
+6

http://www.gamedev.net/community/forums/topic.asp?topic_id=509479&whichpage=1� –

+1

Dobry link. Fora gamedev.net zawsze dostarczały mi wielu informacji. – luke

+0

Linki mogą być pomocne, ale ta odpowiedź nie zawiera więcej informacji niż te linki. Jeśli te stają się niedostępne, ta odpowiedź nie jest już pomocna. – IInspectable

9

Możesz również ponownie otworzyć strumienie cout i cerr, aby wyprowadzić je również do pliku. Poniższa powinien pracować na to:

#include <iostream> 
#include <fstream> 

int main() 
{ 
    std::ofstream file; 
    file.open ("cout.txt"); 
    std::streambuf* sbuf = std::cout.rdbuf(); 
    std::cout.rdbuf(file.rdbuf()); 
    //cout is now pointing to a file 
    return 0; 
} 
3

tworząc rury, wykonać CreateProccess konsoli programu() i odczytać z ReadFile() lub pisze w konsoli WriteFile()

HANDLE hRead ; // ConsoleStdInput 
    HANDLE hWrite; // ConsoleStdOutput and ConsoleStdError 

    STARTUPINFO   stiConsole; 
    SECURITY_ATTRIBUTES segConsole; 
    PROCESS_INFORMATION priConsole; 

    segConsole.nLength = sizeof(segConsole); 
    segConsole.lpSecurityDescriptor = NULL; 
    segConsole.bInheritHandle = TRUE; 

if(CreatePipe(&hRead,&hWrite,&segConsole,0)) 
{ 

    FillMemory(&stiConsole,sizeof(stiConsole),0); 
    stiConsole.cb = sizeof(stiConsole); 
GetStartupInfo(&stiConsole); 
stiConsole.hStdOutput = hWrite; 
stiConsole.hStdError = hWrite; 
stiConsole.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; 
stiConsole.wShowWindow = SW_HIDE; // execute hide 

    if(CreateProcess(NULL, "c:\\teste.exe",NULL,NULL,TRUE,NULL, 
     NULL,NULL,&stiConsole,&priConsole) == TRUE) 
    { 
     //readfile and/or writefile 
}  

}

1

Przejdź do Project> Project Properties> Linker> System iw prawym panelu ustaw SubSystems opcja do Konsola (/ PODSYSTEM: KONSOLA)

Następnie skompiluj swój program i uruchom go z poziomu konsoli, aby sprawdzić, czy wiersz polecenia pokazuje swoje wyniki, czy nie.

2

Jeśli wysyłasz dane wyjściowe programu do pliku lub potoku, np.

myprogram.exe > file.txt 
myprogram.exe | anotherprogram.exe 

albo są wywoływanie programu z innego programu i przechwytywanie swoją moc przez rurę, a następnie nie trzeba nic zmieniać. To zadziała, nawet jeśli punktem wejścia jest WinMain.

Jeśli jednak program jest uruchamiany w konsoli lub w programie Visual Studio, dane wyjściowe nie będą wyświetlane w konsoli ani w oknie wyjściowym programu Visual Studio. Jeśli chcesz zobaczyć wynik "na żywo", wypróbuj jedną z pozostałych odpowiedzi.

Zasadniczo oznacza to, że standardowe wyjście działa tak samo jak w przypadku aplikacji konsolowych, ale nie jest podłączone do konsoli, na której jest uruchomiona aplikacja, i wydaje się, że nie ma na to łatwego sposobu (wszystkie inne Przedstawione tu rozwiązania łączą wyjście z nowym oknem konsoli, które pojawi się po uruchomieniu aplikacji, nawet z innej konsoli.

2

Używając kombinacji luke's answer i Roger's answer here pracował dla mnie w moim projekcie aplikacji Windows Desktop.

void RedirectIOToConsole() { 

    //Create a console for this application 
    AllocConsole(); 

    // Get STDOUT handle 
    HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE); 
    int SystemOutput = _open_osfhandle(intptr_t(ConsoleOutput), _O_TEXT); 
    FILE *COutputHandle = _fdopen(SystemOutput, "w"); 

    // Get STDERR handle 
    HANDLE ConsoleError = GetStdHandle(STD_ERROR_HANDLE); 
    int SystemError = _open_osfhandle(intptr_t(ConsoleError), _O_TEXT); 
    FILE *CErrorHandle = _fdopen(SystemError, "w"); 

    // Get STDIN handle 
    HANDLE ConsoleInput = GetStdHandle(STD_INPUT_HANDLE); 
    int SystemInput = _open_osfhandle(intptr_t(ConsoleInput), _O_TEXT); 
    FILE *CInputHandle = _fdopen(SystemInput, "r"); 

    //make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog point to console as well 
    ios::sync_with_stdio(true); 

    // Redirect the CRT standard input, output, and error handles to the console 
    freopen_s(&CInputHandle, "CONIN$", "r", stdin); 
    freopen_s(&COutputHandle, "CONOUT$", "w", stdout); 
    freopen_s(&CErrorHandle, "CONOUT$", "w", stderr); 

    //Clear the error state for each of the C++ standard stream objects. We need to do this, as 
    //attempts to access the standard streams before they refer to a valid target will cause the 
    //iostream objects to enter an error state. In versions of Visual Studio after 2005, this seems 
    //to always occur during startup regardless of whether anything has been read from or written to 
    //the console or not. 
    std::wcout.clear(); 
    std::cout.clear(); 
    std::wcerr.clear(); 
    std::cerr.clear(); 
    std::wcin.clear(); 
    std::cin.clear(); 

} 
+0

Doskonałe rozwiązanie. –