コンソール入出力関数
多くのCの処理系には、標準入出力関数とほぼ同等の機能を持ちながら、コンソールと直接やり取りをしてデータを入出力する関数群が用意されています。
標準入出力関数のメリット
これまで、データの入力にはscanfやgetchar、データの出力にはprintfやputchar、putsなどの関数を用いてきました。これらは標準入出力(standard Input / Output)を使った機能で、OSの種類に関わらず使用できます。
Linux向けに作ったプログラムのソースをMS-DOSに移植するような場合に、少なくとも標準入出力関数の部分はソースを書き直す必要がなくなります。これは書き直しの手間を省くだけではなく、書き直しによって発生するかもしれないバグの混入を防ぐ、という意味でも大きなメリットです。
汎用であるがゆえのデメリット
しかし、汎用的に使用できる標準入出力関数は、汎用であるがゆえに不便な部分もあります。たとえば、ユーザーに確認を求める処理でgetchar関数を使った場合、
[Y]{Enter]
のように、たった1文字入力するだけでも[Enter]キーを押さなければならず、ユーザーに余計な手間をかけることになります。Y(Yes)またはN(No)のような単純な入力では、[Y]または[N]キーを押すだけで続く[Enter]キーは不要――という仕様のほうが親切です。
[Enter]キーを押さなくても押したキーの内容を受け取ることのできる処理は、OSの提供する標準入力を避けて、コンソール(キーボードやディスプレイそのもの)と直接データをやり取りすることで実現できます。
コンソール入出力関数
そのための関数を「コンソール入出力関数」などと呼び、多くの処理系にはそれらを集めた「コンソール入出力ライブラリ」が用意されています。LSI-Cでは、ソースの冒頭で“conio.h”を取り込むことによって、これらの関数を使用できます。
LSI-Cに用意されているコンソール入出力関数の一部を、表1に掲げておきます。これらはMS-DOSでしか利用できないOS依存の関数群です。
表1:LSI-C 86に用意されている主なコンソール入出力関数
cgets |
機能 |
コンソールから文字列を入力 |
宣言 |
char *cgets(char *s); |
説明 |
引数sのs[1]には入力された文字数、s[2]以降に入力された文字列を格納する。同時に戻り値として文字列へのポインタ(s[2])を返す。文字列の終端にはNULL(\0)が付加され、改行コードは格納されない。 |
cputs |
機能 |
コンソールへの文字列出力 |
宣言 |
void cputs(const char *s); |
説明 |
引数のポインタsで示す文字列をコンソールに出力する。
改行文字(¥n)は出力されない。 |
cscanf |
機能 |
コンソールからの書式付き入力 |
宣言 |
int cscanf(const char *format, ...); |
説明 |
入力元がコンソールに限定されていることを除いて、scanfと同じ機能を持つ。
引数formatの書式もscanfと同じ。
戻り値は値が正常に代入された変数の数。エラー時にはEOF。 |
cprintf |
機能 |
コンソールへの書式付き出力 |
宣言 |
int cprintf(const char *format,...); |
説明 |
出力先がコンソールに限定されていることを除いて、printfと同じ機能を持つ。
引数formatの書式もprintfと同じ。 |
kbhit |
機能 |
コンソールからキー入力があるかどうかを調べる。 |
宣言 |
int kbhit(void); |
説明 |
キーボードが押されていれば0以外の値、押されていなければ0を返す。
押されて入力されたキーの値はgetchまたはgetcheで受け取ることができる。 |
getch getche |
機能 |
コンソールからの1文字(1バイト)入力 |
宣言 |
char getch(void);
char getche(void); |
説明 |
コンソールから1文字だけを入力する。[Enter]キーによる改行の入力は不要。
戻り値は入力された1文字。
getchは入力された文字をコンソールに表示(エコーバック)しない。
getcheは入力された文字をコンソールに表示(エコーバック)する。 |
putch |
機能 |
コンソールへの1文字出力 |
宣言 |
char putch(char c); |
説明 |
引数cをコンソールに出力する。
戻り値は出力された文字。 |
getch関数を使った例
コンソール入力を使った例を紹介しておきましょう。本コラムの第13回「エラーメッセージと対処方法(3)~開発手順の効率化」で、エディタでソースを編集~コンパイラでコンパイル――という処理をエラーが出なくなるまで繰り返すDOSのバッチファイルを紹介しました(リスト1)。
このバッチファイルの中で、プロンプトを表示して編集したソースを再コンパイルするか、終了するかをユーザーに問い合わせるためのプログラム“yesno.exe”を使いました。そのソースがリスト2のyesno.cです。
第13回ではコンソール入力を紹介していなかったので、ユーザーの入力を求める処理ではgetchar関数を使いました。従って、ユーザーは
[Y][Enter]
のように、必ず[Enter]キーを押さなければなりませんでした。この部分をリスト3のようにgetch関数に変更すれば、ユーザーは[Y]または[N]キーを押すだけで済みます。
★注意
サンプルでは、リスト2のyesno.cをex4701.c、リスト3のyesno.cをex4702.cとして収録しています。リスト1のバッチファイルで試す場合は、実行形式ファイルの名前を変更するか、バッチファイル内の“YESNO”の部分を書き換えてください。
リスト1:コンパイル・エラー修正・再コンパイルを自動実行するバッチファイル~CMK.BAT
ECHO OFF
CLS
IF [%1] == [] GOTO ERR
:START
ECHO %1 コンパイル中...
LCC -j -oC:¥CLANG¥EXE¥%1.EXE C:¥CLANG¥SRC¥%1.C > C:¥CLANG¥SRC¥%1.ERR
IF ERRORLEVEL 1 GOTO EDIT
GOTO SUCCESS
:EDIT
C:¥WINDOWS¥SYSTEM32¥NOTEPAD.EXE C:¥CLANG¥SRC¥%1.ERR
↑エディタは適宜書き換えてください
YESNO 再コンパイルしますか?
IF ERRORLEVEL 1 GOTO EXIT
GOTO START
:SUCCESS
ECHO コンパイルは成功しました!
GOTO EXIT
:ERR
ECHO CMK : ファイル名を指定してください。拡張子は不要です。
:EXIT
リスト2:プロンプトを表示して'y'または'n'の入力を受け付ける~yesno.c(ex4701.c)
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char strMessage[255] = "Are you ready?";
int chAnswer;
if (argc > 1)
strcpy(strMessage, argv[1]);
strcat(strMessage, " <y/n>");
puts(strMessage);
chAnswer = getchar(); -------- 1文字の入力を受け取る
if (chAnswer == 'y' || chAnswer == 'Y')
return(0);
else
return(1);
}
リスト3:getch関数を使ったyesno.c(ex4702.c)
/* --------------------------------------------------------------
yesno.c -- メッセージを表示してY/Nの入力を待つ。
[Y]なら0、[N]なら1を終了コードとして返す。
-------------------------------------------------------------- */
#include <stdio.h>
#include <string.h>
#include <conio.h>
int main(int argc, char *argv[])
{
char strMessage[255] = "Are you ready?";
int chAnswer;
if (argc > 1)
strcpy(strMessage, argv[1]);
strcat(strMessage, " <y/n>");
puts(strMessage);
chAnswer = getch(); -------- [Enter]なしの1文字入力
if (chAnswer == 'y' || chAnswer == 'Y')
return(0);
else
return(1);
}
|
|
|