第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み 第14章 ファイル操作 14.1 ファイルへの書き込み 14.2 ファイルからの読み込み 14.3 ファイルへの追加書き込み 14.4 ファイル名の指定 14.5 複数のファイルの同時オープン 14.6 ファイルの構造 14.7 その他のファイル入出力関数
14.0 はじめに これまでのプログラミングの学習では、 入力データは 結果は画面に表示 いわば、その場限りの処理だった… 14.0 はじめに これまでのプログラミングの学習では、 入力データは プログラム中で設定 キーボードから入力 結果は画面に表示 データを入力してください。3 8 和は 11 いわば、その場限りの処理だった…
14.0 はじめに ファイルの操作が必要 一般的なプログラミングでは、 入力データは 結果は別の ファイルに 保存 プログラム中で 14.0 はじめに 一般的なプログラミングでは、 入力データは Excel等のアプリケーションで作成 画像や音声ファイル キーボードから入力 結果は別の ファイルに 保存 プログラム中で ファイルの操作が必要
今日のポイント ファイルへのデータの書き込み ファイルからのデータの読み込み FILE *fp; fp=fopen("ファイル名", "w"); fprintf(fp, "書式指定子", 書き込む変数); fclose(fp); ファイルからのデータの読み込み fp=fopen("ファイル名", "r"); fscanf(fp, "書式指定子", &読み込む変数);
14.1 ファイルへの書き込み プログラム例 14.1.1 #include <stdio.h> int main(void) 14.1 ファイルへの書き込み プログラム例 14.1.1 #include <stdio.h> int main(void) { double a, b, sum; FILE *fp; a = 2.345; b = 5.678; sum = a + b; fp = fopen("foo.txt", "w"); fprintf(fp, "%f, %f, %f¥n", a, b, sum); fclose(fp); return 0; } ファイルポインタの宣言 FILE 型のポインタ変数 fp
14.1 ファイルへの書き込み プログラム例 14.1.1 #include <stdio.h> int main(void) 14.1 ファイルへの書き込み プログラム例 14.1.1 #include <stdio.h> int main(void) { double a, b, sum; FILE *fp; a = 2.345; b = 5.678; sum = a + b; fp = fopen("foo.txt", "w"); fprintf(fp, "%f, %f, %f¥n", a, b, sum); fclose(fp); return 0; } ファイルを開く foo.txt はファイル名 w は書き込みのファイルモード ファイル識別子を txt にしておくとダブル クリックによりメモ帳で開くことができる
14.1 ファイルへの書き込み プログラム例 14.1.1 #include <stdio.h> int main(void) 14.1 ファイルへの書き込み プログラム例 14.1.1 #include <stdio.h> int main(void) { double a, b, sum; FILE *fp; a = 2.345; b = 5.678; sum = a + b; fp = fopen("foo.txt", "w"); fprintf(fp, "%f, %f, %f¥n", a, b, sum); fclose(fp); return 0; } ファイルにデータを書き込む fp で書き込むファイル(foo.txt)を指定 あとは printf と同じ
14.1 ファイルへの書き込み プログラム例 14.1.1 #include <stdio.h> int main(void) 14.1 ファイルへの書き込み プログラム例 14.1.1 #include <stdio.h> int main(void) { double a, b, sum; FILE *fp; a = 2.345; b = 5.678; sum = a + b; fp = fopen("foo.txt", "w"); fprintf(fp, "%f, %f, %f¥n", a, b, sum); fclose(fp); return 0; } 実行後に例14.1.1 のフォルダ内に foo.txt ができていることを確認する 必ず閉じること! ファイルを閉じる
14.2 ファイルからの読み込み プログラム例 14.2.1 #include <stdio.h> int main(void) 14.2 ファイルからの読み込み プログラム例 14.2.1 ファイルポインタの宣言 FILE 型のポインタ変数 fp #include <stdio.h> int main(void) { double a, b, sum; FILE *fp; fp=fopen("foo.txt", "r"); fscanf(fp, "%lf, %lf, %lf¥n", &a, &b, &sum); printf("a=%f, b=%f, sum=%f¥n", a, b, sum); fclose(fp); return 0; } ファイルを開く foo.txt はファイル名 r は読み込みのファイルモード 実行前に例14.1.1 でできた foo.txt を 例14.2.1 の Debug フォルダにコピーしておく
14.2 ファイルからの読み込み プログラム例 14.2.1 #include <stdio.h> int main(void) 14.2 ファイルからの読み込み プログラム例 14.2.1 #include <stdio.h> int main(void) { double a, b, sum; FILE *fp; fp=fopen("foo.txt", "r"); fscanf(fp, "%lf, %lf, %lf¥n", &a, &b, &sum); printf("a=%f, b=%f, sum=%f¥n", a, b, sum); fclose(fp); return 0; } ファイルからデータを読み込む fp で読み込むファイル(foo.txt)を指定 あとは scanf と同じ 実行前に例14.1.1 でできた foo.txt を 例14.2.1 の Debug フォルダにコピーしておく
14.2 ファイルからの読み込み プログラム例 14.2.1 #include <stdio.h> int main(void) 14.2 ファイルからの読み込み プログラム例 14.2.1 #include <stdio.h> int main(void) { double a, b, sum; FILE *fp; fp=fopen("foo.txt", "r"); fscanf(fp, "%lf, %lf, %lf¥n", &a, &b, &sum); printf("a=%f, b=%f, sum=%f¥n", a, b, sum); fclose(fp); return 0; } 必ず閉じること! ファイルを閉じる 実行前に例14.1.1 でできた foo.txt を 例14.2.1 のフォルダにコピーしておく
14.3 ファイルへのデータの追加 プログラム例 14.3.1 #include <stdio.h> 14.3 ファイルへのデータの追加 プログラム例 14.3.1 実行前に例14.1.1 でできた foo.txt を 例14.3.1 の Debug フォルダにコピーしておく #include <stdio.h> int main(void) { double a, b, sum; FILE *fp; a = 1.134; b = 2.567; sum = a + b; fp=fopen("foo.txt", "a"); fprintf(fp, "%f, %f, %f¥n", a, b, sum); fclose(fp); return 0; } 既存のファイルにデータを書き込む fp で書き込むファイル(foo.txt)を指定 "a" なら foo.txt の EOF から書き込むモード(a は append の意) 実行後に例14.3.1 のフォルダにある foo.txt の追加内容を確認
14.4 ファイル名を指定 プログラム例 14.4.1 #include <stdio.h> int main(void) { 14.4 ファイル名を指定 プログラム例 14.4.1 #include <stdio.h> int main(void) { double a, b, sum; char rfile[15]; FILE *fp; printf("データの保存されたファイルの名前を入力して下さい."); gets(rfile); fp=fopen(rfile, "r"); fscanf(fp, "%lf, %lf, %lf", &a, &b, &sum); printf("a=%f, b=%f, sum=%f¥n", a, b, sum); fclose(fp); return 0; } 実行前に例14.1.1 でできた foo.txt を 例14.4.1 のフォルダにコピーしておく 文字列 rfile にファイル名を読み込む 実行時には foo.txt を入力
14.4 ファイル名の確認 プログラム例 14.4.2 #include <stdio.h> int main(void) { 14.4 ファイル名の確認 プログラム例 14.4.2 #include <stdio.h> int main(void) { double a, b, sum; FILE *fp; if ((fp = fopen("baz.dat", "r")) != NULL) { fscanf(fp, "%lf, %lf, %lf¥n", &a, &b, &sum); printf("a=%f, b=%f, sum=%f¥n", a, b, sum); fclose(fp); } else printf("ファイルが存在しません.\n"); return 0; ファイルポインタ fp が NULL でない. (baz.dat というファイルが存在する)なら真 → ファイルからデータを読み込む部分に進む. != は「等しくない」という関係演算子(p.182) ファイル読み書きに良く使う文なので、マスターしよう
14.4 ファイル名の確認の詳細 fopen("baz.dat", "r") fp=fopen("baz.dat", "r") 14.4 ファイル名の確認の詳細 fopen("baz.dat", "r") baz.dat が同じフォルダに存在する → baz.dat へのポインタ baz.dat が同じフォルダに存在しない → NULL fp=fopen("baz.dat", "r") ファイルポインタ fp に fopen 関数の値(baz.dat へのポインタか NULL)を代入 (fp=fopen("baz.dat", "r")) != NULL fp が NULL と等しくない時 → 真(1) NULL の時 → 偽(0) if ((fp=fopen("baz.dat", "r")) != NULL) もし、ポインタ変数 fp が NULL でない(=baz.dat というファイルが存在)なら真 → ファイルからデータを読み込む部分に進む
14.4 ファイル終端の検出 プログラム例 14.4.3 #include <stdio.h> 14.4 ファイル終端の検出 プログラム例 14.4.3 #include <stdio.h> int main(void) { double x[100], y[100]; int i; FILE *fp; fp = fopen("foo.txt", "r"); i = 0; while (fscanf(fp, "%lf, %lf", &x[i], &y[i]) != EOF) { printf("%f, %f\n", x[i], y[i]); i++; } fclose(fp); printf("ファイル中のデータ (x, y) の数は %d 組です.\n", i); return 0; fscanf 関数の値が EOF と等しくない(= fp が 指すファイルの終端でない)間は、{ } を繰り返す 実行前に例14.4.3 のフォルダに p.135 の 最下段のデータをメモ帳で作成し、 foo.txt という名前で保存
14.4 ファイル終端の検出の詳細 fscanf(fp, "%lf, %lf", &x[i], &y[i]) 14.4 ファイル終端の検出の詳細 fscanf(fp, "%lf, %lf", &x[i], &y[i]) fp が指すファイルにデータがある場合 → データを読み込んで配列 x, y に代入する fp が指すファイルにこれ以上のデータがない (ファイル終端)、または何らかのエラーの場合 → EOF while (fscanf(fp, "%lf, %lf", &x[i], &y[i]) != EOF) { … } fscanf 関数の値が EOF と等しくない(fp が指すファイルの終端でない)間は、{…} を繰り返す。
14.5 複数のファイルを同時に開く プログラム例 14.5.1 #include <stdio.h> 14.5 複数のファイルを同時に開く プログラム例 14.5.1 実行前に例14.4.3 で作成した foo.txt を 例14.5.1 のフォルダにコピーしておく #include <stdio.h> int main(void) { FILE *ifp, *ofp; double a, b, sum; ifp = fopen("foo.txt", "r"); ofp = fopen("bar.txt", "w"); while (fscanf(ifp, "%lf, %lf", &a, &b) != EOF) { sum = a + b; fprintf(ofp, "%f, %f, %f¥n", a, b, sum); } fclose(ofp); fclose(ifp); return 0; 読み込むファイル、 書き込むファイルを 指すポインタ 両方とも閉じる 実行後に例14.5.1 のフォルダに bar.txt ができていることを確認する
14.6 ファイルの構造 実際には、以下の例のような構造を持つファイルが多い 1件分をレコードという 各項目をフィールドという 14.6 ファイルの構造 実際には、以下の例のような構造を持つファイルが多い 1件分をレコードという 各項目をフィールドという このようなファイルを「シーケンシャルアクセスファイル」という 興味のある人は 第16章 構造体 を自習してください. 「データ構造とアルゴリズム」や「演習II」で本格的に取り組むはず.
14.7 その他のファイル入出力関数 プログラム例 14.7.1 はファイル間のコピー ファイルコピーは OS上(Windowsならエクスプローラ)でファイルを複製するほうが実際的 主な入出力関数は p.185 に掲載 興味のある人は、いろいろ試してみる
演習問題14.1(レポートの準備) こんなファイルをつくる y = 2x2 + 3 (-10≦ x ≦10) を刻み幅 1 で計算し、x, y の組を1行ごとにファイル(data1.txt)に書き込むプログラム(q14_1.c) を作成せよ。(プログラム例 14.1.1 参照) ビルド・実行してプロジェクト(q14_1)内の Debug (またはRelease) フォルダ内に data1.txt ができているか、エクスプローラで確認せよ アイコンをダブルクリックしてデータを確認せよ -10.000000, 203.00000 -9.000000, 165.00000 -8.000000, 131.00000 -7.000000, 101.00000 ・ ・ ・ ・ こんなファイルをつくる
演習問題14.1のヒント #include <stdio.h> int main(void) { int i; double x, y; FILE *fp; fp=fopen("data1.txt", "w"); for (i = -10; i <= 10; i++) { fprintf(fp, "%f, %f\n", x, y); } fclose(fp); return 0; i を用いた x の式 x を用いた y の式
スキルアップタイム1(レポート課題) 以下の機能を持つプログラム(q14_s1.c)を作成せよ 演習14.1 で作ったファイルdata1.txt を開く data1.txt から x と y を読み取ってディスプレイに表示する(p.136, および例14.4.3参照) x と y は double型の配列とする プログラム例14.2.1 を参考に 21組なのでループが必要 簡単なのは for文 デキる人はプログラム例14.4.3 を参考に while文で
スキルアップタイム1のヒント1 #include <stdio.h> #define N 21 int main(void) { double x[N], y[N]; int i; FILE *fp; fp=fopen("data1.txt", "r"); for (i = 0; i < N; i++) { } fclose(fp); return 0; ファイルからデータを読み込む文 ディスプレイに表示する文
スキルアップタイム1のヒント2 #include <stdio.h> #define N 101 int main(void) { double x[N], y[N]; int i; FILE *fp; fp=fopen("data1.txt", "r"); i = 0; while ( ) { i++; } fclose(fp); return 0; ファイルからデータを読み込み、 EOF でないかをチェックする式 ディスプレイに表示する文
スキルアップタイム2(レポート課題) スキアップタイム1 で作成したプログラムに以下の 機能を追加し、進化させる(q14_s2.c) プログラム中で z = x3 - 75x を計算する z はdouble型の配列とする x, y, z を新しいファイル data2.csv に書き込む データの間はコンマで区切る データの間をコンマで区切り、ファイルの識別子を csv に しておくと、ダブルクリックにより Excel で開くことができる
スキルアップタイム2のヒント1 #include <stdio.h> #define N 21 int main(void) { double x[N], y[N], z[N]; int i; FILE *ifp, *ofp; ifp=fopen("data1.txt", "r"); ofp=fopen("data2.csv", "w"); for (i = 0; i < N; i++) { } fclose(ifp); fclose(ofp); return 0; ファイルからデータを読み込む文 ディスプレイに表示する文 z[i]を計算する文 x[i],y[i],z[i]をファイルに書き込む文
スキルアップタイム2のヒント2 #include <stdio.h> #define N 101 int main(void) { double x[N], y[N], z[N]; int i; FILE *ifp, *ofp; ifp=fopen("data1.txt", "r"); ofp=fopen("data2.csv", "w"); i = 0; while ( ) { i++; } fclose(ifp); fclose(ofp); return 0; ファイルからデータを読み込み、EOF でないかをチェックする式 ディスプレイに表示する文 z[i]を計算する文 x[i],y[i],z[i]をファイルに書き込む文
スキルアップタイム3(レポート課題) データファイル data2.csv を Excelで開く(ダブルクリックでOK) 横軸 x、縦軸を y (および z )とし、 y = 2x2 + 3 z = x3 - 75x のグラフを作成する (第3回レポートの練習) data2.xls に保存する 散布図を 用いること
スキルアップタイム4 スキルアップタイム3 までできた人は、演習問題14.5 からできるところまで.
プログラミング入門II 第2回レポート(任意) 課題:本日のスキルアップタイム 1と2と3 提出期限:2007年11月16日17:00 提出場所:ネットワーク実験室(1)の入口近くの箱 今回のレポートでは以下の項目をいれること. 表紙は不要 学籍番号、氏名 問題番号 ソースリスト 実行結果とグラフ 感想(5行以上書く) レポートのファイルは 保存しておくこと