ファイル出力の例として、ディスプレイに出力していた"Hello World !!"をファイルに書 き出す。リスト1のプログラムを実行させて、作成されたファイル (hello.txt)をエディター(emacsなど)で内容を確認しよう。
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 }
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 }
教科書に書いてあるとおり、高水準ファイル処理と低水準ファイル処理が、通常 は前者を使う。前者はバッファーを文字や数値単位、あるいは文字単位で処理す る関数が用意されており、容易にプログラムができる。それに対して、後者はバ イト単位で処理するので、細かい処理ができるが扱いは面倒である。
改行コードの処理により、テキストモードとバイナリーモードを使い分ける。 Linux(UNIX)ではC言語と同じ改行コードを使う。したがって、テキストモードも バイナリーモードも同じ結果が得られる。Windowsの場合は、テキストモードだ と改行コードの変換が行われるので、注意が必要である。この辺の所は教科書を 見て欲しい。
ファイルのデータへのアクセス方法には、シーケンシャルファイル処理とランダ ムファイル処理がある。前者はデータを先頭から順にアクセスし、後者は任意の 場所からアクセスできる。本講義ではランダムアクセル処理を使うことはない。
fprintf()関数は、標準出力(ディスプレイ)と同じ使い方ができる。画面に 出力するのと同じイメージでファイルに書き込むことができるので、容易にプロ グラムが書ける。実際、出力したファイルをemacsのようなエディターで見ると画 面出力と同じである。
fscanf()関数は、標準入力(キーボード)と同じ使い方ができる。キーボード からデータを入力するのと同じイメージでファイルからデータを読み込むことが できる。諸君は、その方法になれているので、容易にプログラムが書けるだろう。
リスト1や2のプログラムの中で、これらの約束事の記述 の例を図2に示す。人間の動作を考えれば、取 り立ててその流れは難しくない。
図2を見て分かるように、実際のC言語ではオープン と読み書き、クローズの他に、ファイルポインターの宣言が必要であ る。ファイルポインターについては、次の節で述べることにする。C言語のプログラムで ファイル処理をする場合は、図3に示す手順に従えば良い。 ただし、実際のプログラムではエラー処理を書かなくてはならないが、ここでは示してい ない。
すべてこのファイルポインター(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にまとめてある。 細かいファイル処理をする場合は、これらのモードを巧みに使う必要があるが、本講義で は、
ファイルをクローズする関数fclose()の書式は、簡単で、次の通りである。
int fclose(FILE *filepointer)戻り値は、int型で、クローズに成功すると0、失敗するとEOFが返される。引数は、ファ イルポインターのみである。ファイルを開いたら閉じるのが礼儀だと心得て、処理の最後 に書きましょう。
まず、入力からですが、一般のファイルと標準入力の場合を並べて書くと
となる。ファイルポインターを指定する以外、すべて標準入力の場合と同じである。非常 に単純で簡単である。実際の動作もキーボードからデータを入力するのも、ファイルから 読み込むのも同じイメージで取り扱える。
ファイル入力 int fscanf(ファイルポインター,書式指定,引数並び) 標準入力 int scanf(書式指定,引数並び)
出力もまったく同じである。
ハードディスクのファイルにデータを書き込むのは、ディスプレイにデータを出力するのと全く同 じイメージである。実際、ファイル出力されたデータを見ると、ディスプレイと同じであ ることが分かる。
ファイル出力 int fprintf(ファイルポインター ,書式指定,引数並び) 標準出力 int printf(書式指定,引数並び)
これで、コンソール入出力をしつこく詳細に説明した理由がわかったでしょう。コンソー ル入出力とファイル入出力は同じ取り扱いができるのである。
リスト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 }
リスト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 }