2008-10-10 5 views
26

Если у меня есть встроенная программа Windows C++ (т. Е. Точка входа WinMain), как я могу просмотреть вывод из функций консоли, таких как std :: cout?Как получить консольный вывод на C++ с помощью программы Windows?

+1

Вы пытаетесь прочитать выходные данные или выходные данные приложения? – 2008-10-10 15:26:09

ответ

0

Поскольку нет консольного окна, это невозможно сложно. (Узнайте, что-то новое каждый день - я никогда не знал о функциях консоли!)

Возможно ли заменить ваши выходные вызовы? Я часто использую TRACE или OutputDebugString для отправки информации в окно вывода Visual Studio.

+2

На самом деле, возможно, но сложно, чтобы получить консольное окно для программ, используя точку входа WinMain() вместо main(). – 2008-10-10 15:30:24

+0

@ChrisCharabaruk: Это не очень сложно назвать [AllocConsole] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms681944.aspx). Это объясняется в разделе [создание консоли] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms682528.aspx). Кроме того, имя введенной пользователем точки входа не контролирует создание консоли. Это запись заголовка PE для подсистемы, которая делает (`WINDOWS` и` CONSOLE`). Visual Studio использует эту настройку компоновщика для управления, в которой пользователь вводит точку входа в код запуска CRT. – IInspectable 2017-02-20 09:50:24

2

Не цитируйте меня на этом, но Win32 console API может быть тем, что вы ищете. Однако, если вы просто делаете это для целей отладки, вас может заинтересовать в запуске DebugView и вызове функции DbgPrint.

Это, конечно же, предполагает, что ваше приложение вы хотите отправить консольный вывод, а не читать его из другого приложения. В этом случае трубы могут быть вашим другом.

+0

Согласно ссылке на `DbgPrint`, это означает, что` Только драйверы режима ядра могут вызывать процедуру DbgPrint``. Так что, вероятно, не то, что большинство людей хочет – Paladin 2016-05-23 07:26:40

+0

Huh. Ну, я знаю, что есть функция пользовательского режима для регистрации сообщений, которые появятся в DebugView. Я думал, что это DbgPrint, но, очевидно, нет. – 2016-05-24 14:11:45

19

Отъезд Adding Console I/O to a Win32 GUI App. Это может помочь вам сделать то, что вы хотите.

Если у вас нет или не можете изменить код, попробуйте найти найденные предложения here, чтобы перенаправить вывод консоли в файл.


Edit: бит потока некромантии здесь. Я впервые ответил на это 9-летним давным-давно, в ранние дни SO, прежде чем (хорошая) политика ответов, не связанных с ссылкой, вступила в силу. Я отправлю код из оригинальной статьи в надежде искупить мои прошлые грехи.

guicon.cpp - Функция перенаправления консоли

#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 - Интерфейс консоли функция Перенаправление

#ifndef __GUICON_H__ 
#define __GUICON_H__ 
#ifdef _DEBUG 

void RedirectIOToConsole(); 

#endif 
#endif 

// End of File 

test.cpp - Демонстрация перенаправления консоли

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

Вы также можете снова открыть потоки cout и cerr для вывода в файл. Следующие должны работать для этого:

#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

создания канала, выполнить консольную программу CreateProcess() и читать с ReadFile() или пишет в консоли 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

Перейдите в Project> Project Properties> Linker> System и в правой панели, установите SubSystems опция Консоль (/ SUBSYSTEM: CONSOLE)

Затем скомпилируйте свою программу и запустите ее с консоли, чтобы узнать, выводит ли командная строка ваши выходы или нет.

2

Если вы отправляете выходные данные своей программы в файл или канал, например.

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

или вы вызываете программу из другой программы и захватив его выход через трубу, то вам не нужно ничего менять. Он будет работать, даже если точка входа WinMain.

Однако, если вы запускаете свою программу на консоли или в Visual Studio, то вывод не будет отображаться в консоли или в окне вывода Visual Studio. Если вы хотите увидеть результат «вживую», попробуйте один из других ответов.

В принципе, это означает, что стандартный вывод работает так же, как с консольными приложениями, но он не подключен к консоли, на которой вы запускаете приложение, и, похоже, нет простого способа сделать это (все остальные решения, представленные здесь, подключают вывод к новому окну консоли, который появится при запуске приложения даже с другой консоли).

2

Использование комбинации luke's answer и Roger's answer here работало для меня в моем проекте Windows Desktop Application.

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(); 

} 
Смежные вопросы