【C言語マクロ】についての質問ですが、昔、N88BASICの命令ライクなマクロを作って使っていたのですが、昔のマクロは今のCでは、エスケープシーケンスが使えなかったり、PC9801に機種依存していて使えないようです。以下のマクロを今風に実現しようとしたらどうなりますか?教えて下さい。コンパイラはBorland C++です。部分回答でもよいです。


#define CLS() fprintf(stderr,"\x1b[2J") /* Noリダイレクト */
#define LOCATE(x,y) fprintf(stderr,"\x1b[%d;%dH",((y)+1),((x)+1)) /* (0-79,0-24) */
#define COLOR(c) fprintf(stderr,"\x1b[%dm",(c)+30) /* 0:黒,1:赤,2:緑,3:黄,4:青,5:紫,6:水,7:白.(+10:反転) */
#define INKEY_S() (bdos(6,0xff,0) & 0xff) /* dos.hが必要 */
#define mpeek(seg,off) (*(char far *)(((unsigned long)seg<<16)+off)) /* POS_0, CSRLIN で使用 */
#define POS_0() (mpeek(0x0060,0x011c)) /* カーソル列取得 98メモリ直接読取り */
#define CSRLIN() (mpeek(0x0060,0x0110)-mpeek(0x0060,0x011e)) /* カーソル行取得 */

回答の条件
  • 1人1回まで
  • 登録:
  • 終了:2010/07/05 00:37:16
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:Kityo No.2

回答回数161ベストアンサー獲得回数12

ポイント100pt

 LOCATE()とCLS()の例をお見せします。

#define LOCATE(x,y)	gotoxy( (x)+1, (y)+1 )	/* conio.hが必要 */
#define CLS()		system( "cls" )		/* stdlib.hが必要 */

/* 以下はBorland C++ 5.5.1 for Win32で「bcc32 a.cpp」のようにコンパイル&リンクして動作確認した使用例 */
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>


void main( void )
{
	system( "mode CON COLS=80 LINES=25" );
	CLS();
	LOCATE( 1,1 );	printf( "*" );
	LOCATE( 2,2 );	printf( "*" );
	LOCATE( 3,3 );	printf( "*" );
	LOCATE( 4,3 );	printf( "*" );
	LOCATE( 4,3 );	printf( "*" );
	LOCATE( 5,3 );	printf( "*" );
	LOCATE( 5,4 );	printf( "*" );
	LOCATE( 5,5 );	printf( "*" );
	getch();
}

 上のCLS()マクロは、ほぼ全てのDOSとWindowsのDOS窓及びそれら用のC/C++コンパイラの環境で使えると思います。

 LOCATE()マクロは、Borland系のC/C++コンパイラの環境でDOSとWindowsのDOS窓に互換性がある筈です。

 LOCATE()マクロについて、WindowsのDOS窓にスクロールバーが表示されるような状況では期待と違う動きをするかも知れません。

f:id:Kityo:20100703082822j:image

 予めDOS窓のプロパティで、バッファサイズとウインドウサイズを80x25などの無難な大きさで揃えておくなどすると良いと思います。

 DOS窓のプロパティを手動で設定する代わりに、main()関数の冒頭などで「system( "mode CON COLS=80 LINES=25" );」をコーディングしておくのでも良いと思います。

 カテゴリに「ネタ・ジョーク」とあり・質問文面でも「部分回答でもよい」と言って頂いているのに甘えて、ごく一部分だけの中途半端な回答をさせて頂きました。

 rsc96074さんがもしFreeCommandLineToolsとして公開されている無償版のbcc32コンパイラをお使いなら、ライブラリヘルプが付属していないことが主なご不便なのだろうと思います。登録は必要ですが、BCB6 Japanese Help Contentをダウンロードしてみては如何でしょうか? バージョンは異なりますが、充分に役立つと思います。

 rsc96074さんであれば、上のヘルプを見たほうが手っ取り早いのだろうと思います。ダウンロードした場合は目も眩むほどのヘルプファイルが得られますが、取り敢えずは~/Japanese/Help/bcb6.hlp辺りを開けば便利と思います。

id:rsc96074

回答ありがとうございます。LOCATEは私の考えたのと同じでした。CLSは、その方法は思いつきませんでした。私の質問は頭の体操の一面もあるので凝った回答大歓迎です。

ちなみに、私の考えたというか、見つけたのは、CLSの場合、clrscr()関数で代用するものです。COLORもtextcolor(c)という関数がありましたが、実際に試してみましたが、エラーにはなりませんでしたが、色は変わりませんでした。(^_^;

2010/07/03 11:14:27

その他の回答1件)

id:koriki-WeKan No.1

回答回数342ベストアンサー獲得回数20

ポイント10pt

DOS窓アプリでやろうとしているなら、いずれも無理

id:rsc96074

アプリというよりコンソールプログラムです。ちなみに、自分でも検索していますが、CLS()とLOCATE(x,y)は、なんとかなりそうです。ヒントは、Borland C++では、Turbo Cの関数が使えるようです。(^_^;

2010/07/03 07:30:48
id:Kityo No.2

回答回数161ベストアンサー獲得回数12ここでベストアンサー

ポイント100pt

 LOCATE()とCLS()の例をお見せします。

#define LOCATE(x,y)	gotoxy( (x)+1, (y)+1 )	/* conio.hが必要 */
#define CLS()		system( "cls" )		/* stdlib.hが必要 */

/* 以下はBorland C++ 5.5.1 for Win32で「bcc32 a.cpp」のようにコンパイル&リンクして動作確認した使用例 */
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>


void main( void )
{
	system( "mode CON COLS=80 LINES=25" );
	CLS();
	LOCATE( 1,1 );	printf( "*" );
	LOCATE( 2,2 );	printf( "*" );
	LOCATE( 3,3 );	printf( "*" );
	LOCATE( 4,3 );	printf( "*" );
	LOCATE( 4,3 );	printf( "*" );
	LOCATE( 5,3 );	printf( "*" );
	LOCATE( 5,4 );	printf( "*" );
	LOCATE( 5,5 );	printf( "*" );
	getch();
}

 上のCLS()マクロは、ほぼ全てのDOSとWindowsのDOS窓及びそれら用のC/C++コンパイラの環境で使えると思います。

 LOCATE()マクロは、Borland系のC/C++コンパイラの環境でDOSとWindowsのDOS窓に互換性がある筈です。

 LOCATE()マクロについて、WindowsのDOS窓にスクロールバーが表示されるような状況では期待と違う動きをするかも知れません。

f:id:Kityo:20100703082822j:image

 予めDOS窓のプロパティで、バッファサイズとウインドウサイズを80x25などの無難な大きさで揃えておくなどすると良いと思います。

 DOS窓のプロパティを手動で設定する代わりに、main()関数の冒頭などで「system( "mode CON COLS=80 LINES=25" );」をコーディングしておくのでも良いと思います。

 カテゴリに「ネタ・ジョーク」とあり・質問文面でも「部分回答でもよい」と言って頂いているのに甘えて、ごく一部分だけの中途半端な回答をさせて頂きました。

 rsc96074さんがもしFreeCommandLineToolsとして公開されている無償版のbcc32コンパイラをお使いなら、ライブラリヘルプが付属していないことが主なご不便なのだろうと思います。登録は必要ですが、BCB6 Japanese Help Contentをダウンロードしてみては如何でしょうか? バージョンは異なりますが、充分に役立つと思います。

 rsc96074さんであれば、上のヘルプを見たほうが手っ取り早いのだろうと思います。ダウンロードした場合は目も眩むほどのヘルプファイルが得られますが、取り敢えずは~/Japanese/Help/bcb6.hlp辺りを開けば便利と思います。

id:rsc96074

回答ありがとうございます。LOCATEは私の考えたのと同じでした。CLSは、その方法は思いつきませんでした。私の質問は頭の体操の一面もあるので凝った回答大歓迎です。

ちなみに、私の考えたというか、見つけたのは、CLSの場合、clrscr()関数で代用するものです。COLORもtextcolor(c)という関数がありましたが、実際に試してみましたが、エラーにはなりませんでしたが、色は変わりませんでした。(^_^;

2010/07/03 11:14:27
  • id:rsc96074
     INKEY_S()につきましては、下記以外でお願いします。
    #define INKEY_S() (kbhit() ? getch() : 0) /* conio.hが必要 */
  • id:taknt
    MS-DOS上で実行させるならば エスケープシーケンスは 使えるかも?!
  • id:Kityo
     質問者さん(rsc96074さん)、ごめんなさい。
     必死で回答を書き込んでいるうちに第1回答への返信に「CLS()とLOCATE(x,y)は、なんとかなりそう」との書き込みが追加されているのを見逃しました。
     僕の回答は、直接的にはその「なんとかなりそう」にしか答えていません。
     「ヒントは、Borland C++では、Turbo Cの関数が使えるようです。(^_^;」に鑑みると、僕の回答内容だとネタバレに該当してしまうかも知れません。
  • id:Kityo
    >COLORもtextcolor(c)という関数がありましたが、<中略>、色は変わりませんでした。(^_^;
     textcolor(c)した後の文字列の出力には、printf()ではなくてcprintf()を使うと色が反映されると思います。
  • id:cx20
    Borland C++ だと、コンソール API 使わなくてもテキストウィンドウ操作ができるんですね。
    知りませんでした。

    ちょっと調べたところ、参考になりそうな情報がありましたので、URL を載せておきます。

    ■ GrWinを用いたグラフィクス・プログラミング
    http://www.ee.fukui-nct.ac.jp/~yoneda/text/other/C/a_01.htm
    ■ conio.h で提供される関数,マクロの説明(オンラインヘルプ)
    http://docs.embarcadero.com/products/rad_studio/radstudio2007/RS2007_helpupdates/HUpdate4/JA/html/devwin32/coniohpart_xml.html
    ■ conio.hに見る Windows用Cランタイムの コンソール関数のサポート状況:プログラムやフォントなど:So-netブログ
    http://gonbee.blog.so-net.ne.jp/2005-08-16-2

    ちなみに、座標取得ですが、gettextinfo() で、いけるようです。
    以下はマクロにした場合の例です。もっと良い方法があるかもしれないですが、参考まで。

    #define POS_0() GetTextXPos()
    #define CSRLIN() GetTextYPos()

    int GetTextXPos( void )
    {
     struct text_info ti;
     gettextinfo(&ti);
     return ti.curx;
    }

    int GetTextYPos( void )
    {
     struct text_info ti;
     gettextinfo(&ti);
     return ti.cury;
    }
  • id:rsc96074
     コメントありがとうございます。
    cprintfにしたら、色変わりました。
    それから、POSやCSRLINもなんとかいけそうです。ただ、起点補正(0-79,0-24)のために、1を引いてみました。
    #define POS_0() (GetTextXPos()-1)
    #define CSRLIN() (GetTextYPos()-1)
     cx20さんも遠慮されずに、コメント欄のをそのままでもいいので回答欄につけて下さい。

  • id:rsc96074
     So-netブログのとこにあるwherex()とwherey()も使えそうです。
    #define POS_0() (wherex()-1)
    #define CSRLIN() (wherey()-1)
  • id:rsc96074
     皆さん、ありがとうございました。とりあえず、みんな揃ったみたいです。
     #1の方は、はじめ1ptにしようかと思いましたが、07:07:07の大当たりで10倍差し上げます。(^_^;
  • id:cx20
    > So-netブログのとこにあるwherex()とwherey()も使えそうです。

    そのものずばりの関数が用意されていたようですね。失礼しました。

    蛇足ですが、VC++ で Win32 API を使ったサンプルがありましたので参考まで。

    ■ Programのプ:VC++で作る
    http://www.asahi-net.or.jp/~qb3k-kwsk/rpg/program/tutorial/game1/m100.html
  • id:rsc96074
    コメント有難うございます。
  • id:Kityo
     もしrsc96074さんがプロフェッショナルで・ご自分の目の届かないところでも利用される可能性のあるコンソールアプリケーションをリリースされようとしているのであれば、Borlandの<conio.h>のこの辺りの関数は避けたほうが良いと思います。
     と言うのも自分は、FreeCommandLineToolsとして公開されている無償版のbcc32コンパイラに付属のライブラリのgotoxy()とwherex()\wherey()に関しては以前に利用を検討したことがあります。
     調査した詳細な内容は忘れてしまいましたが、結論としては「ちょっと挙動が怪しいのでWindowsのコンソールAPIと直接向き合ってオリジナルのgotoxy()等を作ったほうが良い」と言った調査結果でした。
     具体的なところでは、(DOS窓のプロパティで)バッファサイズを大きくしたりすると(例:300x300)思ったところにカーソルを動かせなかったりした記憶があります。また自分のコンソールアプリが実行している最中に(マウスなどでユーザーが)ウインドウサイズを変更した場合に適切な再表示を行なおうとする場合にも何か問題があったと記憶しています。

     上のような状況はサポートする予定がなくて・ご自分の手元で落ち着いたバッファサイズ(例:80x25)で使う分には、Borlandの<conio.h>の関数は勿論充分に実用的です。
     頭の体操…とおっしゃっているところに、真面目な話で恐縮でした。

    ---
     コンソールAPIについては、僕の昔の質問で参考になるURLや書籍をたくさん見つけて貰いました。http://q.hatena.ne.jp/1241807256
  • id:rsc96074
    コメント有難うございます。

この質問への反応(ブックマークコメント)

トラックバック

  • 分散と相関係数(2)  分散と相関係数などを求めるプログラムをCで書いてみました。ついでに、前回の自分の質問で分かったコンソールマクロも付けてみました。 #include &lt;stdio.h&gt; #include &
「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません