2 ファイル処理関数(18章)

2.1 ファイル処理の体験

2.1.1 ファイル出力

ごちゃごちゃとファイル処理について、説明する前に、実際にファイル処理を体験してみ よう。

ファイル出力の例として、ディスプレイに出力していた"Hello World !!"をファイルに書 き出す。リスト1のプログラムを実行させて、作成されたファイル (hello.txt)をエディター(emacsなど)で内容を確認しよう。

4行
ファイルポインターの宣言。
6行
ファイルのオープン
8行
ファイルへの書き込み
10行
ファイルのクローズ

   1 #include <stdio.h>
   2 
   3 int main(void){
   4   FILE *fp;
   5 
   6   fp=fopen("hello.txt","w");
   7 
   8   fprintf(fp,"Hello World !!\n");
   9 
  10   fclose(fp);
  11 
  12   return 0;
  13 }

2.1.2 ファイル入力

先ほど作成したファイル(hello.txt)の内容を読み、それを画面に出力してみよう。
5行
ファイルポインターの宣言。
8行
ファイルのオープン
10行
ファイルからデータの読み込み
14行
ファイルのクローズ

   1 #include <stdio.h>
   2 
   3 int main(void){
   4 
   5   FILE *fp;
   6   char a[32], b[32], c[32], tmp;
   7 
   8   fp = fopen("hello.txt", "r");
   9 
  10   fscanf(fp, "%s%s%s%c", a, b, c, &tmp);
  11 
  12   fclose(fp);
  13 
  14   printf("%s %s %s\n", a, b, c);
  15 
  16   return 0;
  17 }

2.2 数値計算のファイル入出力

C言語のファイル入出力は、用途に応じた処理ができるように、様々な機能が用意されて いる。しかし、数値計算で使う場合、以下のようにすれば良い。この辺りについては、す ぐに理解できなくても良いが、ファイル処理を多用するプログラムを作成する場合には各 自勉強して欲しい。ただ、教科書にはいろいろ書かれているので、諸君がこの講義で必要 なファイル処理の機能をまとめているだけである。

2.3 ファイル処理の流れと関連事項

2.3.1 処理の流れ

ほとんどのプログラム言語では、ファイルの処理は図1のよう になっている。これは人間が、データを記録している本やノートなどを見る動作と全く同 じようになっている。オープン読み書きクローズは約 束事と理解して欲しい。また、同時に複数個のファイルをオープンすることも可能である。
図 1: コンピューターのファイル処理と人間の読み書き方法
\includegraphics[keepaspectratio, scale=1.0]{figure/flow_file_manage.eps}

リスト12のプログラムの中で、これらの約束事の記述 の例を図2に示す。人間の動作を考えれば、取 り立ててその流れは難しくない。

図 2: C言語でのファイル処理の例

2を見て分かるように、実際のC言語ではオープン読み書きクローズの他に、ファイルポインターの宣言が必要であ る。ファイルポインターについては、次の節で述べることにする。C言語のプログラムで ファイル処理をする場合は、図3に示す手順に従えば良い。 ただし、実際のプログラムではエラー処理を書かなくてはならないが、ここでは示してい ない。

図 3: C言語でのファイル処理の流れ
\includegraphics[keepaspectratio, scale=1.0]{figure/flow_file_manage_C.eps}

2.3.2 オープンとクローズ

C言語では、かなり細かいファイルの処理ができる。そのために、ファイルの情報をメモ リーの一部に格納する必要がある。その格納場所を示すものがファイルポインターである。 それは構造体になっており、stdio.hというヘッダーファイルにその内容が定義され ている。定義内容の例が教科書(p.377)に書かれている。以下のようなことが記述されて いる。

すべてこのファイルポインター(fp)を使って、ファイル関係の処理は実施する事になる。なに せ、ファイルに関する情報が全て書かれているので、これを指定すれば、あとはコン ピューターが勝手に処理してくれる。面倒くさい処理はコンピューター任せにして、プロ グラマーは楽をしようということである。このFILE型の変数(ポインター)を使うた めには、次のように宣言する。

FILE *fp;
FILE型の変数(ポインター)fpを宣言したのである。ただし、fpは変数名なので プログラマーが勝手な名前をつけて良い。

通常は、fopen()という関数の戻り値をこのポインターに代入する。このファイルを オープンする関数fopen()の書式は、次の通りである。

FILE *fopen(char *filename, char *openmode)
戻り値はFILE型のポインター、ファイル名を表す第一引数はchar型のポインター、オープ ンモードを表す第2引数はchar型のポインターと言うことである。もし、オープンに失敗 すると、NULLという戻り値になります。char型のポインターと難しいことを言っているが、 先のプログラムの例(リスト1, 2)でも分かるように、文 字列をダブルクォーテーションで囲めば良いのである。例えば、hoge.txtというファイル を読み込みモードでオープンする場合
fp=fopen("hoge.txt", "r");
と書けば良い。

オープンモードについては、いろいろ用意されており、教科書のp.382にまとめてある。 細かいファイル処理をする場合は、これらのモードを巧みに使う必要があるが、本講義で は、

とすればよい。バイナリーモードもUNIX(Linux)では関係ないので使わない。

ファイルをクローズする関数fclose()の書式は、簡単で、次の通りである。

int fclose(FILE *filepointer)
戻り値は、int型で、クローズに成功すると0、失敗するとEOFが返される。引数は、ファ イルポインターのみである。ファイルを開いたら閉じるのが礼儀だと心得て、処理の最後 に書きましょう。

2.3.3 ファイル入出力関数

いよいよ、ファイルのデータを読み書きするファイル入出力関数について説明する。難し そうですが、実は非常に簡単である。いままで、標準入力(キーボード)と標準出力(ディ スプレイ)に使ってきた関数、printf()scanf()とほとんど同じである。 付録に示すようにキーボードやディスプレイもファイルとして取り扱われるので、同じ手 法がハードディスクにも使える。

まず、入力からですが、一般のファイルと標準入力の場合を並べて書くと

ファイル入力 int fscanf(ファイルポインター,書式指定,引数並び)
標準入力 int scanf(書式指定,引数並び)
となる。ファイルポインターを指定する以外、すべて標準入力の場合と同じである。非常 に単純で簡単である。実際の動作もキーボードからデータを入力するのも、ファイルから 読み込むのも同じイメージで取り扱える。

出力もまったく同じである。

ファイル出力 int fprintf(ファイルポインター ,書式指定,引数並び)
標準出力 int printf(書式指定,引数並び)
ハードディスクのファイルにデータを書き込むのは、ディスプレイにデータを出力するのと全く同 じイメージである。実際、ファイル出力されたデータを見ると、ディスプレイと同じであ ることが分かる。

これで、コンソール入出力をしつこく詳細に説明した理由がわかったでしょう。コンソー ル入出力とファイル入出力は同じ取り扱いができるのである。

2.4 ファイル出力の実際

計算結果などを大量のデータはハードディスクに保存しなくてはならない。ファイル出力のコツは、 である。

リスト3に三角関数の値をファイル出力するプログラムを示す。この プログラムを実行して、作成されたファイルを適当なエディター(emacs等)で見よ。

   1 #include <stdio.h>
   2 #include <math.h>
   3 
   4 int main(void){
   5   FILE *out_file;
   6   double x, y1, y2, y3;
   7   double pi, dphi;
   8   int i, n;
   9   
  10   pi = 4.0*atan(1.0);
  11   n = 360;
  12   
  13   dphi = 2*pi/n;
  14   
  15   out_file = fopen("trifunc.txt","w");
  16   
  17   for(i=0; i<=n; i++){
  18     x=i*dphi-pi;
  19     y1 = sin(x);
  20     y2 = cos(x);
  21     y3 = tan(x);		  
  22     fprintf(out_file, "%e\t%e\t%e\t%e\n", x, y1, y2, y3);
  23   }
  24   
  25   fclose(out_file);
  26 
  27   return 0;
  28 }

2.5 ファイル入力の実際

数値計算では、処理の対象となる大量のデータをハードディスクから読み込むことが多い。 数値計算に限らず、現代の実験ではコンピューターのハードディスクにデータが蓄えられ るのは普通である。ハードディスクに保存されたデータを読み出し、それを処理すること が実験のデータ整理に必要となる。このような場合、ファイルからのデータ入力のコツは、 である。

リスト4に先ほど作成したファイル内容を読み込み、ディスプレイに出 力するプログラムを示す。このプログラムを実行して、ファイルの読み込みの練習をせよ。

   1 #include <stdio.h>
   2 
   3 int main(void){
   4   FILE *in_file;
   5   double x[500], y1[500], y2[500], y3[500];
   6   char temp;
   7   int i, j;
   8   
   9   in_file = fopen("trifunc.txt","r");
  10   
  11   for(i=0; i<=499; i++){
  12     if(
  13        EOF == fscanf(in_file, "%lf%lf%lf%lf%c",&x[i], &y1[i], &y2[i], &y3[i], &temp)
  14        ) break;
  15   }
  16   
  17   fclose(in_file);
  18 
  19   for(j=0; j<i; j++){
  20     printf("%f\t%f\t%f\t%f\n",x[j], y1[j], y2[j], y3[j]);
  21   }
  22 
  23   return 0;
  24 }

ホームページ: Yamamoto's laboratory
著者: 山本昌志
Yamamoto Masashi
平成17年7月10日


no counter