C言語-インタプリタminiCASL
前へ 目次へ 次へ 

 6. 入出力命令を追加する

 キーボード入力とディスプレイ出力の命令を追加する。その際、変数が使用できるようにする。
 入力命令はin、出力命令はoutとし、書式は次の通りとする。

in 変数 … キーボードから入力したデータを変数に格納する。
out 変数 … 変数に格納されているデータをディスプレイに出力する。

 変数は実数(double)型のみとし、変数名は1文字a〜zの26種類だけとする。大文字と小文字は区別しない。例えば、変数のAとaは同じものとする。(あとで命令も大文字と小文字のどちらでも使えるようにする。)

 プログラムでは、mc(miniCASL)言語の変数(a〜z)の値を格納しておく変数をグローバル変数(ほかのユーザ関数の中でも参照できるようにするため)として用意する。例えば、配列名をhensuuとする。

fig

 関数mainには、in命令とout命令を判定する if文を追加する(add命令などを判定している場所で!)。
 in命令と判定されたときの処理は次の通りである。

  1. 関数get_tokenで次の語(変数名)を取り出す。
  2. 取り出した語が英字かどうかチェックする。
  3. 「in=」や「データを入力して下さい」のように入力待ちであることがわかるようにプロンプトを表示する。
  4. データを文字列として入力する。例えば配列名をinbuffとする。
  5. 入力データを関数atofで数値に変換し、配列hensuu[変数番号]に記憶する。
    変数番号は、取り出した語を関数toupperで大文字に変換してから計算する。
    関数toupperを利用するには、ctype.hをインクルードする必要がある。

 out命令と判定されたときの処理は次の通りである。

  1. 関数get_tokenで次の語(変数名)を取り出す。
  2. 取り出した語が英字かどうかチェックする。
  3. 配列hensuu[変数番号]に記憶されている値を表示する。

 配列hensuuの何番目に格納するかは、変数名(大文字)から'A'(0x41)を減じて求める。

[mc07.c]
 1:
 2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:

51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "gettoken.h"

#define STRMAX 80       /* 文字列配列の大きさ */
/* グローバル変数 */
double hensuu[26];      /* mc言語の変数用 */

void main(int argc, char *argv[])
{
    double  data1, data2, ans;
    FILE    *fp;        /* ファイル操作用 */
    char    inbuff[STRMAX];     /* 入力データ用 */

    if(argc != 2){      /* パラメータのチェック */
        printf("使い方:MC filename\n");
        exit(1);
    }
    if((fp = fopen(argv[1], "r")) == NULL){     /* ファイルのオープン */
        printf("ファイルがオープンできませんでした。\n");
        exit(1);
    }
    while(fgets(gt_line, STRMAX, fp)){     /* データの読み込み */
        get_token();
        if(!strcmp(token, "add")){    /* 命令判定 */
<< 省 略 >>
        }else if(!strcmp(token, "end")){
            break;
        }else if(!strcmp(token, "in")){
            @           ;               /* 1語取り出し */
            if(!isalpha(*token)){       /* 変数チェック */
                printf("in : 変数を指定してください。\n");
                exit(1);
            }
            printf("in=");
            gets(inbuff);
            hensuu[A        (*token) - 'A'] = atof(inbuff);
        }else if(!strcmp(token, "B    ")){
            get_token();                /* 1語取り出し */
            if(!isalpha(*token)){       /* 変数チェック */
                printf("out : 変数を指定してください。\n");
                exit(1);
            }
            printf("%f\n", hensuu[toupper(*token) - 'A']);
        }else{
            printf("Error : コマンドエラー\n");
            continue;
        }
        printf("%f\n", ans);            /* 結果表示 */
    }
    fclose(fp);         /* ファイルのクローズ */
}
[解答欄] (すべて半角文字で、空白文字もチェックされます。)
@   A   B
     
reidai03.mc
in m
out m
end
実行結果
D:\Data\src>cc mc07.c gettoken.obj
lld @link.i
D:\Data\src>mc07 reidai03.mc
in=12.3456
0.000000
12.345600
0.000000


【問題点】
 実行結果で"in="と表示されたあと適当な数値を入力するとその入力値が0.000000にはさまれて表示される。この0.000000は、76行目にある四則計算の結果を表示するためのprintf()が表示している。

【対策】
 73行目のprintf()を四則計算(例えばans=data1+daat2)4カ所の次の行にそれぞれ書き、73行目を削除する。

 対策の方法はほかにもいろいろと考えられる。
 次に追加する機能でこの問題も解決するので、対策をしたとき別のファイル名で保存すること。mc07.cはこのままとする。


前へ 目次へ 次へ 
Copyright © 2001 Hiroshi Masuda 

 

 

inserted by FC2 system