予定スケジュール ( 全 15 回 ) 1 1. 終了 プログラミング言語の基礎 2. 終了 演算と型 3. 終了 プログラムの流れの分岐 (if 文,switch 文など ) 4. 終了 プログラムの流れの繰返し (do, while, for 文など ) 5. 終了 中間レポート1 6. 終了 配列 7. 終了 関数 8. 終了 文字列 ( 文字列の配列, 文字列の操作 ) 9. 終了 ポインタ ( ポインタ, アドレス, ポインタと配列の関係など ) 10. 終了 中間レポート2 11. 終了 文字列とポインタ ( ポインタによる文字列の操作など ) 12. 終了 予備日 13. 1/12 ファイル処理 14. 1/13 最終レポート ( 統一補講日 ) 15. 1/19 最終レポート このレジュメ, 演習課題のプログラム例は,WebCT, または http://www.ritsumei.ac.jp/~ykubo から閲覧, 印刷可能です.
本日の内容 ( 第 13 章 ) ファイル処理 2 ファイルとストリーム ファイルのオープン クローズ データの読み込み 書き込み テキストとバイナリ データを読み込んだり, 保存したりする ファイル の取り扱いについて学習する
ファイルとストリーム 3 ストリーム : ファイル, キーボード, ディスプレイ, プリンタ等々の周辺機器に対するデータの流れの概念 標準ストリーム stdin: 標準入力ストリーム ( 入力を読み取る. 大抵の場合はキーボード.scanf 関数,getchar 関数など ) stdout: 標準出力ストリーム ( 出力を書き込む. 大抵の場合はディスプレイ.printf 関数,puts 関数など ) FILE 型のポインタ stdio.h で定義 stderr: 標準エラーストリーム ( エラーを書き出す. 大抵の場合はディスプレイ ) FILE 型 (FILE 型はストリームの制御に必要な情報を記録するための型 ) ファイル位置表示子 : 現在アクセスしているアドレスを記録 エラー表示子 : 読み取りエラー 書き込みエラーを記録 ファイル終了表示子 : ファイルの終わりに達したかどうかを記録
ファイルのオープン クローズ 4 ファイルを使用するには, ファイルを オープン する. 使い終わったら クローズ する ファイルのオープン fopen 関数を利用する モードを選択 : 読み取り書き込み更新追加 ファイルのクローズ fclose 関数を利用する
ファイルのオープン クローズ ( 例 ) 5 "abc" というファイルを " 読み取りモード " でオープンし, 閉じるプログラム. オープン出来なかった場合は, ファイルをオープンできません と表示する /* */ List 13-1 ファイルのオープンとクローズ #include <stdio.h> int main(void) { FILE *fp; fp = fopen("abc", "r"); /* ファイルのオープン */ if (fp == NULL) printf(" a ファイルをオープンできません n"); else { /* ファイルから読込みなどを行う */ fclose(fp); /* ファイルのクローズ */ return (0);
ファイルからデータを読み込む 6 Aiba 160 59.3 Kurata 162 51.6 Masaki 182 76.5 Tanaka 170 60.7 Tsuji 175 83.9 Washio 175 72.5 データファイル hw.dat データファイル hw.dat をオープンする fp = fopen("hw.dat","r"); データファイル hw.dat から 名前( 文字列 ) 身長(double 型実数 ) 体重(double 型実数 ) を読み取る. fscanf(fp, "%s%lf%lf", name, &height, &weight); データファイル hw.dat をクローズする fclose(fp);
ファイルからデータを読み込む ( 例 ) 7 /* */ #include <stdio.h> 身長と体重を読み込んで平均値を求めて表示する int main(void) { FILE *fp; int ninzu = 0; /* 人数 */ char name[100]; /* 名前 */ double height, weight; /* 身長 体重 */ double hsum = 0.0; /* 身長の合計 */ double wsum = 0.0; /* 体重の合計 */ List 13-2 Aiba 160 59.3 if ((fp = fopen("hw.dat", "r")) == NULL) /* オープン */ printf(" aファイルをオープンできません n"); else { while (fscanf(fp, "%s%lf%lf", name, &height, &weight) == 3) { printf("%-10s %5.1f %5.1f n", name, height, weight); ninzu++; hsum += height; wsum += weight; printf("---------------------- n"); printf(" 平均 %5.1f %5.1f", hsum / ninzu, wsum / ninzu); fclose(fp); /* クローズ */ return (0); 実行結果 Kurata 162 51.6 Masaki 182 76.5 Tanaka 170 60.7 Tsuji 175 83.9 Washio 175 72.5 --------------------- 平均 170.7 67.4
ファイルにデータを書き込む 8 List13-2( 身長と体重を読み込んで平均値を求めて表示する ) プログラムを改良して, 計算結果をファイルに記録するようにする. データ書き出しファイル kekka.dat をオープンする fp2 = fopen("kekka.dat","w"); ファイル kekka.dat に 平均身長 (double 型実数 ) 平均体重 (double 型実数 ) を書き出す fprintf(fp2, " 平均身長 :%f 平均体重 : %f ", hsum/ninzu, wsum/ninzu); ファイル kekka.dat をクローズする fclose(fp2);
ファイルにデータを書き込む ( 例 ) /* */ List 13-2( 改良 ) 身長と体重を読み込んで平均値を求めて表示する 9 #include <stdio.h> int main(void) { FILE *fp, *fp2; int ninzu = 0; /* 人数 */ char name[100]; /* 名前 */ double height, weight; /* 身長 体重 */ double hsum = 0.0; /* 身長の合計 */ double wsum = 0.0; /* 体重の合計 */ if ((fp = fopen("hw.dat", "r")) == NULL) /* オープン */ printf(" aファイルをオープンできません n"); else { while (fscanf(fp, "%s%lf%lf", name, &height, &weight) == 3) { printf("%-10s %5.1f %5.1f n", name, height, weight); ninzu++; hsum += height; wsum += weight; printf("---------------------- n"); printf(" 平均 %5.1f %5.1f", hsum / ninzu, wsum / ninzu); fclose(fp); /* クローズ */ if ((fp2 = fopen("kekka.dat", "w")) == NULL) /* オープン */ printf(" aファイルをオープンできません n"); else { printf(" 平均身長 : %f 平均体重 : %f", hsum/ninzu, wsum/ninzu); fclose(fp); /* クローズ */ return (0);
テキストファイルとバイナリファイル 10 整数 357, 2057 を fprintf 関数によってファイルに書き出す場合を考えよう (a) テキストで書き出す場合は,1 文字 1 バイトで, 各桁を 文字 として書き出す (b) バイナリで書き出す場合は,int 型の大きさ ( この場合は 2 バイト ) で,2 進数のビットの並びとして書き出す
バイナリファイルへの実数値の保存 11 double 型実数 double pi = 3.14159265358979323846; をバイナリファイルに書き出してみよう データ書き出しファイル kekka.dat をオープンする fp = fopen("kekka.dat","wb"); ファイル kekka.dat に変数 pi (double 型実数 ) に格納された値を書き出す fwrite(&pi, sizeof(double), 1, fp); 先頭番地 (&pi) から, double 型の大きさ のデータを, 1 個, fp が示す対象へ書き出す. 読み出しは? データファイル data.dat をオープンする fp = fopen("data.dat","rb"); ファイル data.dat から double 型実数を 1 個読み取り, 変数 pi に格納する fread(&pi, sizeof(double), 1, fp);
バイナリファイルへの実数値の保存 ( 例 ) 12 /* */ List 13-9 #include <stdio.h> 円周率の値をバイナリファイルに書き込んで読み取る int main(void) { FILE *fp; double pi = 3.14159265358979323846; 実行結果実行結果一例円周率は3.141592653589793116000です /* 書込み */ if ((fp = fopen("pi.bin", "wb")) == NULL) /* オープン */ printf(" a ファイルをオープンできません n"); else { fwrite(&pi, sizeof(double), 1, fp); /* pi を書き込む */ fclose(fp); /* クローズ */ /* 読取り */ if ((fp = fopen("pi.bin", "rb")) == NULL) /* オープン */ printf(" a ファイルをオープンできません n"); else { fread(&pi, sizeof(double), 1, fp); /* pi に読み取る */ printf(" 円周率は %23.21f です n", pi); fclose(fp); /* クローズ */ return (0);
演習課題 13 演習 1 List13-2 のプログラムを改良して, データファイル hw.dat からデータを読み込み, 平均身長, 平均体重を計算し, その結果をデータファイルの末尾に追加するプログラムを作成しなさい.