8章 ファイルの読み書き

 

概要

商品のデータなど、大規模なデータを処理のたびに一つ一つキーボードから入力するのは大変です。そこで、あらかじめ作成されたデータファイルからプログラムにデータを読み込んだり、処理結果をファイルに書き出す方法について学びます。

 

この章の目標

ファイルを用いたデータの読み込み方法を習得する。

ファイルを用いたデータの書き出し方法を習得する。

 

--------------------------------------------

8.1 ファイルからのデータの読み込み

--------------------------------------------

●ファイルを開く・閉じる

fopen関数を使用してデータを読み込むデータファイルを開き、fclose関数を使用してデータファイルを閉じます。fopen関数でファイルを開いた後は、必ずfclose関数でファイルを閉じてからプログラムが終了するようにして下さい。

 

(例)

main()

{

       FILE *fp;

 

       fp = fopen("data","r");

 

       fclose(fp);

}

 

fopen関数の引数は、ファイル名とモードで、上の例の場合、ファイル名「data」というファイルを読み込みモード(r)で開くという指定をしています。このfopen関数は、指定されたファイル名のファイルのポインタを返しますが、ファイルが見つからない場合、NULLの値を返します。

従って、指定したファイルがない場合、プログラムの実行を終了させるように次の例のような記述をよく用います。

 

       if( (fp = fopen("data","r")) == NULL ){

              printf("\n Don't open file [%s]\n","data");

              exit(1);

       }

 

exit関数は、プログラムを終了させます。

 

●データの読み込み

キーボードからの値の読み込みに、scanf関数を用いましたが、ファイルから値を読み込むには、fscanf関数を用います。引数にファイルのポインタを指定すること以外は、scanf関数と同じです。書式等の引数の詳細は、第3章を参照して下さい。

 

P例:8.1-1)

住所録ファイルに書かれているデータを読み込んで、画面に表示するプログラムです。

 

#include<stdio.h>

#include<stdlib.h>

         

main()

{

       char Simei[20],Yuubin[10],Jyuusyo[50];

       FILE *fp;

 

       if( (fp = fopen("data.txt","r")) == NULL ){

              printf("\n Don't open file [%s]\n","data.txt");

              exit(1);

       }

       while( fscanf(fp,"%s",Simei) != EOF ){

              fscanf(fp,"%s",Yuubin);

              fscanf(fp,"%s",Jyuusyo);

 

              printf("%s,%s,%s\n",Simei,Yuubin,Jyuusyo);

       }

       fclose(fp);

}

・データファイル例

流通太郎 135-0044 東京都江東区越中島2-1-6

流通次郎 135-00** 東京都江東区***********

流通三郎 135-00** 東京都江東区***********

 

【注意】

氏名、郵便番号等の区切りは、半角のスペースかタブとして下さい。C言語では、全角スペースはデータの区切りとして扱われません。また、プログラムのソースファイルと同じく、漢字コードと改行コードをUnix環境に変換するのを忘れずに行って下さい。

 

--------------------------------------------

8.2 ファイルへのデータの書き出し

--------------------------------------------

●ファイルを開く・閉じる

データファイルからデータを読み込む場合と同じく、fopen関数を使用してファイルを開き、fclose関数を使用してファイルを閉じます。

異なるのは、fopen関数を用いてファイルを開く際のモードを「w」とし、書き込みモードで開く点のみです。

 

●データの読み込み

fprintf関数を使用して、ファイルに値を書き込みします。この際の書式などは、printf関数と同じです。書式等の引数の詳細は、第3章を参照して下さい。

なお、fscanf関数と同じく、fprintf関数も引数にファイルのポインタを指定します。

 

P例:8.2-1)

このプログラムは、船が旋回する際の軌跡を計算します。ファイルには、1秒毎の座標値が書き出されます。

 

#include<stdio.h>

#include<stdlib.h>

#include<math.h>

 

main()

{

       double x,y,z,dz,ddz,dt;

       double r,T,K,v;

       FILE *fp;

 

       x = y = 0.0;

       z = dz = ddz = 0.0;

 

       dt = 1.0; /* シミュレーションの刻み幅(sec) */

       r = 10.0; /* 舵角 */

 

       printf("速力 v= ");

       scanf("%lf",&v);

       v = v*1852.0/3600.0;

       printf("ゲイン定数 K= ");

       scanf("%lf",&K);

       printf("時定数 T= ");

       scanf("%lf",&T);

 

       if( (fp = fopen("data.txt","w")) == NULL ){

              printf("\n Don't open file [%s]\n","data.txt");

              exit(1);

       }

       fprintf(fp,"\nx,y\n");

       for(;z<=360.0;){

              ddz = K/T*r - 1.0/T*dz;

              dz += ddz*dt;

              z += dz*dt;

              y += v*dt*cos(z*3.14/180.0);

              x += v*dt*sin(z*3.14/180.0);

              fprintf(fp,"%lf,%lf\n",x,y);

       }

       fclose(fp);

}

・コンパイル

このプログラムでは、sinやcosなどの数学関数を使用しています。この場合、ヘッダーファイルとして、math.h が必要となります。

また、コンパイルの際には、下記のようにオプションとして、「-lm」を付けなければなりません。

 

       fcc ファイル名 -lm

 

・入力データ

下記に、船種毎の各係数を示します。船が旋回する際に必要な海域の広さを確認するとともに、船種によっても異なることを確認してみて下さい。

 

操縦性指数(T:追従安定性指数(時定数),K:旋回力指数(ゲイン定数))

 

舵角10度のジグザグ試験による。

船種     状態   長さx幅x深さ   平均喫水   排水量   速力 v     K        T

 (m)             (m)        (トン)     (ノット)      (sec-1)   (sec)

客船             37x7.8x4.1        2.68        362      9.7     0.143     6.2

貨物船   バラスト  106x15.6x8.1      3.04       3275     13.0     0.067     8.3

貨物船   満載   106x16.2x8.0      5.27       6928     14.0     0.110    41.6

タンカー     バラスト  245x32.9x18.5    13.30      89760     17.8     0.064    93.3

タンカー     満載   276x43.0x22.0    16.50     162000     16.5     0.099   201.0

広田 実,船舶制御システム工学<増補版>,p.99,成山堂書店,1984

 

【注意】

プログラムを実行しても画面には、何も表示されません。fprintf関数は、引数で示されたファイルに対してのみ出力します。

--------------------------------------------