標準エラー出力も関連付ける


前回までのプログラムで標準出力関数で文字列を出力できます
が、標準エラーは出力することができません
//標準出力を指定し、標準出力関数を使ってみる
//標準エラーは出力されないことを確認
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <iostream>
#include <io.h>
#include <fcntl.h>
using namespace std;

int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    int hConsole;

    ::AllocConsole();     //コンソール割り当て

    hConsole = ::_open_osfhandle((intptr_t)::GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
    *stdout = *::_tfdopen(hConsole, TEXT("w"));
    ::setvbuf(stdout, NULL, _IONBF, 0);

    printf("printfで出力\n");
    cout<<"coutで出力"<<endl;
    
    fprintf(stderr, "エラー出力\n");
    cerr<<"cerrでエラー出力"<<endl;

    ::MessageBox(NULL, TEXT("ストッパーです"), TEXT("AllocConsole"), MB_OK);
    ::FreeConsole();      //コンソールを解放します
    ::_close(hConsole);   //ハンドルを閉じます

    return 0;
}
標準エラーは出力されない

標準出力の関連付けと同様に標準エラー出力も関連付けてしまえば出力が可能です
また、ワイド文字出力系の関数で日本語を出力するにはロケールの設定が必要です
//標準出力を指定し、標準出力関数を使ってみる
//標準エラーも出力される
//UNICODEコンパイル対応
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <iostream>
#include <io.h>
#include <fcntl.h>
using namespace std;

//割り込み制御
BOOL WINAPI HandlerRoutine(DWORD type)
{
    switch(type)
    {
    case CTRL_C_EVENT:      //Ctrl+Cを受け取った
    case CTRL_BREAK_EVENT:  //Ctrl+Breakを受け取った
    case CTRL_CLOSE_EVENT:  //コンソールを閉じた
        return TRUE;        //無効にするのでTRUEを返す
    case CTRL_LOGOFF_EVENT:
    case CTRL_SHUTDOWN_EVENT:
        return FALSE;
    }
    return FALSE;           //それ以外の時は強制終了
}

int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    int hStdOut, hStdErr;

    ::AllocConsole();     //コンソール割り当て

    //標準出力関連付け
    hStdOut = ::_open_osfhandle((intptr_t)::GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT);
    *stdout = *::_tfdopen(hStdOut, TEXT("w"));
    ::setvbuf(stdout, NULL, _IONBF, 0);

    //標準エラー出力関連付け
    hStdErr = ::_open_osfhandle((intptr_t)::GetStdHandle(STD_ERROR_HANDLE), _O_TEXT);
    *stderr = *::_tfdopen(hStdErr, TEXT("w"));
    ::setvbuf(stderr, NULL, _IONBF, 0);

    //割り込みハンドラ関数追加
    ::SetConsoleCtrlHandler(HandlerRoutine, TRUE);
    
    //ロケールの設定
    ::_tsetlocale(LC_ALL, TEXT("japanese"));
    
    ::_tprintf_s(TEXT("標準出力\n"));
    ::_ftprintf_s(stderr, TEXT("エラー出力\n"));

#ifdef _UNICODE
    wcout<<L"wcoutで出力"<<endl;
    wcerr<<L"wcerrでエラー出力"<<endl;
#else
    cout<<"coutで出力"<<endl;
    cerr<<"cerrでエラー出力"<<endl;
#endif

    ::MessageBox(NULL, TEXT("ストッパーです"), TEXT("AllocConsole"), MB_OK);
    ::FreeConsole();      //コンソールを解放します
    ::_close(hStdOut);    //ハンドルを閉じます
    ::_close(hStdErr);

    return 0;
}
左)UNICODEビルド 右)マルチバイトビルド
標準エラーも出力 標準エラーも出力
GetStdHandleがSTD_ERROR_HANDLEで呼び出しています
そして開いたハンドルをstderrに関連付けています

次は標準入力についてです

続き


TOPプログラミング>標準エラー出力も関連付ける