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

 2. mbasのプログラムファイルからプログラムリストを読み込む

 ファイル処理の基本的な手順は、次のとおりである。

  1. ファイルオープン
  2. ファイル読み込み(書き込み)
  3. ファイルクローズ

 プログラムリストは文字列なので、文字列を格納しておくには文字型の配列を使用することになる。例えば、

char list[256];

と宣言すると、255文字格納することができる。プログラムは1行単位で処理していくので、1行を1つの変数に格納するようにする方が処理しやすい。

char list[100][256];
reidai01.mb
INPUT "Teihen=",t
INPUT "Takasa=",h
s = t * h / 2
PRINT "Menseki=";s
END

と宣言することで、100行分(1行最大255文字)格納することができる。reidai01.mbを読み込んで格納すると次のようなイメージになる。

 この方法(char list[100][256];)では、100 * 256 = 25600バイトものメモリを使用し、例えば、END命令のように3文字(ナル文字を含めて4文字)でも1行分256文字用意することになり、メモリの使用効率が悪い。
 そこで、必要なメモリ領域(命令文を格納するため)を必要なときに確保する関数mallocが用意されている。

x = malloc(4);

を記述すると、メモリに4バイト分の領域を確保する。変数xには、確保した領域の先頭番地が格納される。これを利用するとメモリの無駄が少なくて済む。
 1行分格納するためのバイト数は、1行の文字数 + 1(ナル文字の分)である。1行の文字数は、関数strlenで求めることができる。変数char buff[256];を用意し、1行分読み込むとき、

x = malloc(strlen(buff) + 1);

で必要なメモリ領域が確保される。
 確保した領域には、文字列を格納し、その先頭番地は変数xに格納されるので、変数xはchar型のポインタとして宣言する必要がある。また、関数mallocで求まる値も同じ型にする必要がある。正確には、次のように記述する。

char  *x;
x = (char *)malloc(strlen(buff) + 1);

 このポインタ変数xを必要な行数分用意すればよいことになる。例えば、

char  *x[100];

のように配列にすれば100行分用意することになる。
 さらに、関数mallocはメモリに必要なバイト数の領域を確保するだけであるから、確保できた領域にデータをコピーする必要がある。

[mbas01.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:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main(int argc, char *argv[])
{
    char    *list[100];     /* プログラムリスト用 */
    char    buff[256];      /* 1行読み込み用      */
    FILE    *fp;            /* ファイルポインタ   */
    int     now = 0;        /* 行数カウント       */
    int     last;           /* 最終行             */

    if(argc != 2){          /* ファイル名指定なし */
        printf("ファイル名の指定がありません\n");
        exit(1);                /* 強制終了 */
    }
    /* ファイルのオープン */
    if((fp = fopen(@     , "r")) == NULL){
        printf("ファイルがオープンできません\n");
        exit(1);
    }
    /* ファイルの読み込み */
    while(fgets(buff, 256, fp) != NULL){        /* 1行読み込み */
        list[now] = (char *)malloc(strlen(A  ) + 1);   /* 領域確保 */
        if(list[now] == NULL){
            printf("領域確保に失敗しました\n");
            exit(1);
        }
        strcpy(list[now], buff);    /* 確保した領域にデータコピー */
        ++now;
    }
    last = now;         /* 最終行番を格納 */
    /* ファイルのクローズ */
    fclose(fp);
    /* 読み込んだリスト表示 */
    for(now = 0; now < last; ++now)
        printf("%s",B      );
}
[解答欄] (すべて半角文字で、空白文字もチェックされます。)
@    A    B
     
実行結果
D:\Data\src>cc mbas01.c
lld @link.i
D:\Data\src>mbas01
ファイルがオープンできません

D:\Data\src>mbas01 reidai01.mb
INPUT "Teihen=",t
INPUT "Takasa=",h
s = t * h / 2
PRINT "Menseki=";s
END


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

 

 

inserted by FC2 system