ファイルに書く?
プログラムのデバッグなどでは、よく「ログファイル」というファイルに情報を出力してデバッグを行います。
自身のプログラムのデバッグや動作確認のためだけにファイルに出力させることは、HDD全盛の時代には普通にやっていました。
Visual Studioが使える環境の場合、Visual Studioで「出力」ウィンドウに出力させることも可能です。
(Visual Studioの「出力」ウィンドウに文字列を出力する場合はOutputDebugString()関数が定番ですし、ツールさえあればこの情報を見ることも可能です)
SSD(Solid State Drive)が普及している昨今、一時的に自分が見たいという理由だけでファイルに出力したりするのもどうしたものかと思い、調べてみました。
ここでは、Visual Studioや外部ツールなどを使わずに、GUIアプリケーションで文字列を表示させる方法を紹介します。
AllocConsole関数
そのまんまですが、Windows APIにはAllocConsole関数という関数があります。
AllocConsole関数は、プロセスに新しいコンソールを割り当てる為の関数です。
この関数を呼び出すと,画面にコンソールが表示されます。
実装してみる
この関数を使った部分のサンプルコードです。
小さい関数を作ってみました。
void DispConsole() { // コンソールを作成する AllocConsole(); // 標準入出力に割り当てる FILE* fp = NULL; // 昔のコード //freopen("CONOUT$", "w", stdout); //freopen("CONIN$", "r", stdin); // 現在のコード freopen_s(&fp, "CONOUT$", "w", stdout); freopen_s(&fp, "CONIN$", "r", stdin); }
この関数をプログラムの先頭などで呼び出すと、Windowsコンソールが表示されます。
ちょっと便利に使うために’freopen’という、普段は見慣れない関数がありますので併せて紹介しておきます。
詳細な説明は、MSDNにお任せするとして「新たにファイルをオープンし、ストリームと結びつける・・・」関数なんですが、
この関数は、最近のVisual Studioなどで使おうとおするとコンパイラからの警告(警告レベル設定によってはエラー)”C4996″が出ます。
似たようなことは、「fopen関数」でも発生します。
対策方法は2通り(厳密には3通り)あります。
- 適切な関数に置き換える
- 警告が出ないようにする
「1. 適切な関数に置き換える」は、サンプルコードのように関数呼出そのものを置き換える。
というものです。
こういった警告を出す関数はほとんど代わりになる関数が用意されています。
「2. 警告が出ないようにする」は、関数呼び出しなどのコードは変更せずに、コンパイラからの警告が出ないようにする。
というものです。
「pragma warning」や、「_CRT_SECURE_NO_WARNINGS」を用いる。といった方法です。
今回使用している関数(freopen関数)では、freopen_s関数に置き換える。という方法を取りました。
まとめ
この「Windows GUIプログラムでデバッグ情報をコンソールを表示させる」は、Visual Studioなどがある環境では使わないように思われるかもしれません(実際、出番はめったにありません)。
ただ、この方法でコンソールを表示している場合のメリットは、
- デバッグで変数を出力する処理を記述する(実装する)手間が省力化できる。
- ファイルに出力しないのでディスクにやさしい(ちょっとですが・・・)。
くらいです。
「デバッグで変数を出力する処理を記述する(実装する)手間が省力化できる。」というのは、コンソールの標準出力が使用できるので’printf関数’を使った書式化した出力が一行で書けます。
OutputDebugString()(デバッグ出力用文字列出力関数)は、文字列が完成していないといけないので、書式化した出力を行いたい(特に変数の値を表示したい)のときに、必ず当関数呼び出しの前に文字列バッファへ自分で文字列を生成させなければなりません。