2013-02-23 3 views
3

응용 프로그램 내부에서 사용자 지정 콘솔을 표시하는 클래스를 작성하고 있습니다. 나는 또한 glog을 사용하여 메시지를 파일에 기록하고 동시에 stderr에 기록합니다. 콘솔 클래스가 stderr를 듣게하려면 어떻게해야합니까? 사용자 지정 응용 프로그램 콘솔 및 stderr

나는 사용자 정의 fstream을 생각하고 같은 일을 뭔가 :

CustomStream cs; 
auto original_buf = std::cerr.rdbuf(cs.rdbuf()); 

및 콘솔 클래스로 전송 stream operator <<에 대한 호출을 가지고.

또는 서브 클래스를 직접 std::filebuf와 통화에서 :

CustomFilebuf fb; 
auto original_buf = std::cerr.rdbuf(&fb); 

이 그것을 할 올바른 방법인가? 몇 가지 샘플 코드를 검색했지만 찾지 못했습니다.

Edit1 : 스트림 티를 사용해 보았지만 이 아니라 이 아닌 로그가 기록되어 데이터를 가져올 수 없었습니다.

+0

당신이 * * stderr에 듣고 무엇을 의미합니까 (가 열려진 stderr.log 파일 모두에 메시지를 기록합니다)인가? 그리고 glog는 무엇입니까? –

+0

응용 프로그램 내에서 렌더링 할 수 있도록 stderr 출력을 캡처하여 콘솔 클래스로 보내려고합니다. 필자는 새로운 데이터를 반복적으로 폴링하고 싶지 않지만 새로운 메시지가 플러시 될 때 알림을 보내주기 때문에 청취했습니다. –

+2

그러면 나만의 스트림이 필요하지 않습니다.stderr의 내용을 전환시키는 streambuf가 충분해야합니다. 예제는 [Tee streams] (http://wordaligned.org/articles/cpp-streambufs#toctee-streams)을 참조하십시오. –

답변

1
이 질문에 관련이 있다면 불확실입니다

,하지만 ...

ISO C99는 7.19.5.3 말한다, 제 6 항 : 또한

When a file is opened with update mode ('+' as the second or third character in the above list of mode argument values), both input and output may be performed on the associated stream. However, output shall not be directly followed by input without an intervening call to the fflush function [...], and input shall not be directly followed by output without an intervening call to a file positioning function, unless the input operation encounters end-of-file.

일부 열려진에서 읽는 것은 말할 당신은 당신이 플러시 읽기 전에 한, 열려진 읽을 수 있지만 "정의되지 않은 행동"...

:

fwrite("x", 1, 1, stderr); 
fflush(stderr); 
fgetc(stderr); 
,451,515,

도는 Win32 응용 프로그램에서 콘솔 창에 표준 출력을 리디렉션하고 싶은 누군가를 위해 How do I read stdout/stderr output of a child process correctly?


살펴 보도록가 AllocConsole입니다. 여부를 정의 <crtdbg.h>를 포함하면 디버그로 콘솔을 원하는 경우에만 확인

#include <fstream> 
#include <io.h> 
#include <fcntl.h> 

#define cMaxConsoleLines 500 

void ReadyConsole() { 

    short int hConHandle; 
    long lStdHandle; 

    CONSOLE_SCREEN_BUFFER_INFO coninfo; 

    FILE *fp; 

    // Allocate a console for the program 
    AllocConsole(); 

    // set the screen buffer to be big enough to let us scroll text 
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo); 

    coninfo.dwSize.Y = cMaxConsoleLines; // The max number of lines for the console! 

    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize); 


    // Redirect STDOUT to the console 
    lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE); 
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); 

    fp = _fdopen(hConHandle, "w"); // Writing to the console 

    *stdout = *fp; 

    setvbuf(stdout, NULL, _IONBF, 0); 
    // ------------------------------- 


    // Redirect STDIN to the console 
    lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE); 
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); 

    fp = _fdopen(hConHandle, "r"); // Reading from the console 

    *stdin = *fp; 

    setvbuf(stdin, NULL, _IONBF, 0); 
    // ------------------------------ 


    // Redirect STDERR to the console 
    lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE); 
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); 

    fp = _fdopen(hConHandle, "w"); // STDERR writing to the console! 

    *stderr = *fp; 

    setvbuf(stderr, NULL, _IONBF, 0); 
    // ------------------------------ 


    // Point the console to STDIO 
    std::ios::sync_with_stdio(); 

} 

:

가 난 콘솔 창에 표준 출력을 리디렉션하는 간단한 (사소한) 함수를 생성

#ifdef _DEBUG 
// The file with the ReadyConsole function 
#include <DebugStuff.h> 
#endif 

을하고 그것을

#ifdef _DEBUG 
ReadyConsole(); // Ready the console for debugging 
#endif 

#ifdef _DEBUG 
fprintf(stdout, "Position, Line 1, DEBUG-INFO-HERE"); 
cout << "COUT is working!"; // NOTE, for cout, you will need <iostream> 
#endif 
을 사용 : 응용 프로그램이 디버그 모드 (VC에 대한 ++)에, 다음, 예를 들어, 당신은 추가 할 수 있습니다 여기

은 추가 작은 기능

void StdErr(char* Error) { 

    fprintf(stderr, Error); 
    FILE* FP = fopen("stderr.log", "a"); 
    fputs(Error, FP); 
    fclose(FP); 

} 
+0

나는 이미 그것을 사용하고 있지만, 이제는 콘솔 클래스를 바꾸려고했습니다. 표준 콘솔 출력 stderr 및 stdout 자신의, 내가 무엇을 요구하고있다 동일한 클래스를 구현하는 방법입니다. –

+0

오, 아주 좋아. 나는이 문제를 Olaf가 제안한 링크로 해결했다고 추정한다. – Mitch

+0

실제로 아직 편집을 참조하십시오. –

관련 문제