4.22 / * 文字列の非破壊入力 / * 改行のみ入力された場合は , バッフアを更新しない * / VOid get_strx (char *S, 土 n し size) char し emp [ 129 ] : if (*gets (temp) s し rncpy ( s ′し emp , s 土 z e ) : ー Y 0' s [ s 土 z e ] / * 指定された文字集合に含まれる文字を入力 プロンプト ( 入力工ラー時に繰り返す ) * / / * prompt / * charset : 文字集合 char get_charset (char *prompt ′ char *charset) putchar(' Ya' 房 return c•, putchar(' Yn' 房 if (strchr(charset, c) ) / * strchr は文字が見つからないと NULL を返す * / putchar(' Yn' 房 C getche( 房 printf (prompt) : for char C : charset prompt2 promptl / * 簡易メニュー : 選択可能な文字集合 プロンプト 2 ( 入力工ラー時に繰り返す ) * / プロンプト 1 ( 最初に 1 回だけ出力 ) プログラムリスト 2 char get_menu (char *promptl . char *prompt2 , char *charset ) printf (promptl) ー return get_charset (prompt2 ′ charset) 冫
24 スカ文字を制限るには ? メニューなどの選択で , 指定した文字以外の文字を入力させたくないとき があります . この指定以外の文字の入力を防ぐために , 不正な文字が入力さ れた場合はベルを鵈らし , 再度人力をやり直させる関数 get_charset を作り ます . get-charset は , 第 1 引数に画面に表示させたいプロンプト , 第 2 引数に入 力してよい文字集合を指定します . たとえば次のサンプルプログラムでは , Y と N 以外の文字を入力できないようにしています . #include く s し d 土 0 . h> サンプルプログラム 56 ノ 29 #include #include char char get—charset ( char *prompt ′ <string. h> く con 土 0 . h> C : putchar ( ' Y a ' ) : for C : putchar い Yn' 房 if (strchr (charset, putchar ( ・ Yn' 房 c = getche ( 房 printf (prompt) : ・・ getche を使うため ・・ st 「 chr を使うため char *charset )
ノ 32 2 プログラミングの定石 サンプレプログラム 57 #include く s し d 土 0 . h> #inCIUde く con 土 0 . h> #include <string. h> こに 2.4 節の get_charset を置く char get—menu ( char *promptl , char *prompt2 , char *charset ) printf ( pror 叩し 1 房 return get_charset (prompt2 ー charset ) : Char *mnu " メインメニュー Yn" ー Y n" " 1 ] アクションゲーム Y n" " 2 ] ロールプレイングゲーム Y n" " 3 ] シミュレーションゲーム Yn" "0] 終了 YnYn" ・ main ( ) char select; select = get—menu(mnu, " どれで遊びますか ? " printf("%c が選択されました¥ n " , select); return 0 : " 123 0 " ) :
2 4 ・データベース 22.6 misc. h misc . h ーー汎用処理ルーチン 19 94 . 1 . 7 : by K . T VOid get_str(char *s, 土 n し size) ー / * 文字列の入力 : 最大入力文字数指定可能 * / void get_strx(char *s, 土 n し size) : / * 文字列の非破壊入力 * / char get—charset (char *prompt , char *charset) ー / * 指定された文字集合に含まれる文字を入力 * / char get—menu (char *promptl , char *prompt2 , char *charset) 冫 / * 簡易メニュー * / 22.7 misc.c 汎用処理ルーチン ITII S C . C 19 9 4 . 1 . 7 : by K . T #include く s に d 土 0 . h > #include く string . h> #include く土 0 . h > / * 文字列の入力 / * s 土 z e : 最大入力文字数い Y 0 , を含まない純粋な大きさ ) * / バッフアの大きさは si ze + 1 が必要 VOid get_str(char *s, Size) char し emp [ 129 ] : / * s に r s t r * / / * getche * / = MS ー D 〇 s で入力可能な最大文字数 * / / * 12 8 gets(temp) : S 土 Z e ) : strncpy(), temp, s [ s 土 z e ] / * strncpy では temp が size 以上の長さだと ・ Y 0 , が付加されない * / / * fgets(), size, stdin); を使う方法もある ただし , 文字列の最後に Y n が付加される * /
ノ 3 ノ 簡易メニ 25 簡易メこュー ユ 前節の get-charset を利用して , 簡易メニューを処理する get-menu を作 ることができます . この関数を利用する場合は , 2. 1 節で説明した長い文字列を使って , メニ そして , 次のように呼び出します . "0] 終了 YnYn" " 3 ] シミュレーションゲーム Yn" " 2 ] ロールプレイングゲーム Yn " ” 1 ] アクションゲーム Yn" ”メインメニュー Yn" char *mnu ューとなる文字列を定義します . select = get—menu(mnu, ”どれで遊びますか ? ” " 12 3 0 つ冫 第 1 引数は , いま定義したメニューを表す文字列を指定します . 第 2 引数 は , 正しい入力が得られるまで繰り返し出力するプロンプトを指定し , 第 3 引 数は , 正しい入力の文字集合を指定します . 実際の get-menu 内部では , まず第 1 引数を表示した後 , 第 2 引数と第 3 引数を使って前節の get_charset を呼び出しているだけです .
2 プログラミングの定石 main ( ) char select; select = get—charset(" よろしいですか (Y/N) ? " printf("%c が選択されました Yn", select); re turn 0 : 実行例 よろしいですか (Y/N) ・・不正な入力 ( ベルが嗚る ) ? Q よろしいですか (Y/N) これも不正な入力 ( ベルか嗚る ) ? W よろしいですか (Y/N) ・・正しい入力 ? Y Y が選択されました ・入力された文字を示す get-charset の主要部分は , 大きな for ループになっています . for ( ; ; ) は , 初期設定や条件などを何も指定していません . for 文でこう書くと無限ループに なり , re ⅲ rn 文などでループを抜ける指示をしない限り , ループを繰り返します . 全体の構成は , 次のようになります . for プロンプトを出力 1 文字入力 if ( 正しい入力 ) return 入力された文字 : ベルを鳴らす else getche はキーポードから 1 文字人力する関数で , ヘッダファイルく conio. h > が必要です . strchr は第 1 引数の文字列の中に第 2 引数の文字が入っている かを調べ , 入っていればその文字のポインタを返し ( 真 ) , なければ 0 を返しま す ( 偽 ) . strchr は , ヘッダファイル <String. h> が必要です . つまり , 正しい人力が行われていればその文字を返し , 不正な文字が人力 されていればベルをならし再度入力を求めています . 少し複雑な気もします力 : , 実際に自分で入力して動きを確かめてみるとよ いでしよう .