SSブログ

Windowsアプリケーションでprintf [プログラミング]

前回までのあらすじ)
Windowsアプリケーション(GUIプログラム)なのに、実行結果をコマンドプロンプトに表示しなければならなくなった。


Windowsアプリケーションでは、標準入出力が何処にも割り当てられていないので、
printf("Hello, World!");
としても何処にも表示されません。

“何処にも割り当てられていない”が表示されない原因ならば、プログラム上で何処かに割り当ててしまえば万事OKです。

標準入出力の設定は、freopen()関数で行えるのですが、Windowsアプリケーションの場合は、その前にAllocConsole APIを呼ばなければならないことになっているようです。

::AllocConsole();               // コマンドプロンプトが表示される
freopen("CON", "r", stdin);     // 標準入力の割り当て
freopen("CON", "w", stdout);    // 標準出力の割り当て


printf("input no ... \n");              // コマンドプロンプトに表示

int num;
scanf("%d", &num);                      // 入力も可

std::cout << num << std::endl;          // これも使える


::FreeConsole();                // コマンドプロンプトを閉じる

これの難点は、AllocConsoleすると新しいコマンドプロンプトが表示される事(2回実行しても1つだけ)と、FreeConsoleやプログラムの終了でコマンドプロンプトが閉じてしまうこと。

コマンドプロンプトからWindowsアプリケーションを起動したら、そのコマンドプロンプト上に表示される(別のコマンドプロンプトが表示されるのではなくて)のが理想です。

それには、AllocConsoleの代りにAttachConsoleを使用します。

if (!::AttachConsole(ATTACH_PARENT_PROCESS)) {
    ::AllocConsole();           // コマンドプロンプトからの起動じゃない時は新たに開く
}
freopen("CON", "r", stdin);     // 標準入力の割り当て
freopen("CON", "w", stdout);    // 標準出力の割り当て


printf("input no ... \n");
int num;
scanf("%d", &num);
std::cout << num << std::endl;


::FreeConsole();                // 割り当て解除

MSDNによると、AttachConsoleの引数はATTACH_PARENT_CONSOLEとなっていますが、ATTACH_PARENT_PROCESSが正解のようです(Visual C++ .NET 2003の場合)。

ただ、この方法には1つ問題があって、AttachConsole APIはWindows XP以降にしか存在しないのです。


客から「コンソールに出力したい」と要望のあったソフトウェアはWindows 98/2000/XP 対応なのでAttachConsoleは使えません。

そこで、

  1. コンソールアプリケーションは、コマンドライン引数をそのまま引き継いでWindowsアプリケーションを起動
  2. Windowsアプリケーションは結果を、テンポラリファイルに出力
  3. Windowsアプリケーションが終了したら、コンソールアプリケーションがテンポラリファイルの内容を標準出力へ出力

ってな感じのコンソールアプリケーションを作ることで対処しました。

ソースファイルをコピーしてコンソールアプリケーションとWindowsアプリケーションの両方のバージョンのプログラムを作っちゃった方が楽だったようなと思いつつも……。


そして、半年後。
意外な方法で、あっさり解決できることに気付く。

(つづく)

[飛行機] 今日の一冊
暗号化 プライバシーを救った反乱者たち

暗号化 プライバシーを救った反乱者たち

  • 作者: スティーブン・レビー
  • 出版社/メーカー: 紀伊國屋書店
  • 発売日: 2002/02/16
  • メディア: 単行本

タグ:VisualC++
nice!(0)  コメント(1)  トラックバック(0) 

nice! 0

コメント 1

JEX

とてもこの記事が役に立ちました。
ありがとうございます。
by JEX (2008-02-28 11:24) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。