コンピュータープログラミング (C言語)(10) 1.ファイル入出力 コンピュータ基礎実験 第12回 コンピュータープログラミング (C言語)(10) 1.ファイル入出力
ファイル入出力 C言語では、ファイルにデータを出力したり、ファイルからデータを入力する機能があります。 この機能を使うと、画面への出力(printf関数)やキーボードからの入力(scanf関数)とよく似たやり方でファイル入出力が可能です。
ファイルに出力 #include <stdio.h> #include <stdlib.h> int main(void) { ファイル用変数(ファイルポインタ)の 宣言 ファイルをオープン ファイルへの書き込み ファイルをクローズ return 0; } #include <stdio.h> #include <stdlib.h> int main(void) { FILE *f; if((f = fopen(”test.txt”,”w”))==NULL){ printf(”オープン失敗\n”); exit(1); } fprintf(f, ”Hello world!\n”); fclose(f); return 0;
ファイルから入力 #include <stdio.h> #include <stdlib.h> int main(void) { ファイル用変数(ファイルポインタ)の 宣言 ファイルをオープン ファイルから読み込み ファイルをクローズ return 0; } #include <stdio.h> #include <stdlib.h> int main(void) { FILE *f; int i; if((f = fopen(”test.txt”,”r”))==NULL){ printf(”オープン失敗\n”); exit(1); } fscanf(f, ”%d”,&i); fclose(f); return 0;
ファイルオープン時のモード 「fopen(”test.txt”,”w”)」: ”w”部分の文字によってファイルオープンのモードが決定 ”r” 備考 ”r” 読み込みモード read ”w” 書き込みモード write, 新しく上書きされる ”a” 追加書き込みモード append, 末尾に追加書き込み ”r+” 読み書き両用モード ”w+” オープン時に内容がクリア ”a+” 書き込みは必ず末尾 両用モードは混乱の元なので上級者になってから
このプログラムを実行すると,同じフォルダ(ディレクトリ)内に /* --- データの書き込み EX12-1.c --- */ #include <stdio.h> #include <stdlib.h> int main(void) { FILE *f; printf("start ... \n"); if((f=fopen("kekka.txt","w"))==NULL){ printf(“オープン失敗\n"); exit(1); } /* --- ここから計算例 --- */ int i=0, sum=0; do{ sum =sum+i; i++; fprintf(f,"%d %d\n",i-1,sum); }while(i<=20); /* --- ここまで計算例 --- */ fclose(f); printf("finished \n"); return 0; [例題 EX12-1] 次の例を実行せよ. このプログラムを実行すると,同じフォルダ(ディレクトリ)内に kekka.txt というデータファイルが作られる (注) この例は 0から N までの和を 求めるプログラム
データの書き込み /* File 書き込み EX12-1.c */ #include <stdio.h> ■ 次のEX12-1.cは,結果をファイル“kekka.txt”に出力(書き込み)しする例. /* File 書き込み EX12-1.c */ #include <stdio.h> #include <stdlib.h> int main(void) { FILE *f; printf(”start \n"); If((f=fopen("kekka.txt","w") ==NULL){ printf(“オープン失敗\n"); exit(1); } /* --- ここから計算例 --- */ int i=0, sum=0; do{ sum = sum+i; i++; fprintf(f,“%d %d\n”,i-1,sum); }while(i<=20); /* --- ここまで計算例 --- */ fclose(f); printf("finished \n"); return 0; } あくまで 一例 ファイルポインターという、ファイルを指定するための変数「f」を宣言する FILE *f fopen関数による指定 fopen(ファイル名, “w”) …ここで wはファイルへの書き込み ファイルが開けなかったら exit(1) としてプログラムを終了させる fprintf(f, …)でデータを書き込む 終わったらfclose(f)としてファイルを閉じる
データ リスト (注1) 関数 exit exit(status); のように使う ここでstatusは整数 異常がなければ 0 データ リスト EX12-1.exeの実行結果: ファイル"kekka.txt” (注1) 関数 exit exit(status); のように使う ここでstatusは整数 異常がなければ 0 異常があると 0 以外の値 (注2) 関数 fprintf fprintf(f, 書式制御文字列,出力変数) のように使う f以外は printf と同様 0 0 1 1 2 3 3 6 4 10 5 15 6 21 7 28 …….. 15 120 16 136 17 153 18 171 19 190 20 210
このプログラムを実行すると,同じフォルダ(ディレクトリ)内にある [例題 EX12-2] 次の例を実行せよ. /* --- データの読み込み EX12-2.c --- */ #include <stdio.h> #include <stdlib.h> int main(void) { FILE *f; int i,x[100],y[100]; if((f=fopen("kekka.txt","r"))== NULL){ printf("オープン失敗\n"); exit(1); } for(i=0;i<=20;i++){ fscanf(f,"%d %d",&x[i],&y[i]); printf("%d, %d \n", x[i], y[i]); fclose(f); return 0; このプログラムを実行すると,同じフォルダ(ディレクトリ)内にある kekka.txt というファイルからデータが読み込まれる
データの読み込み /* File 読み込み */ #include <stdio.h> ■ 次の例は,ファイル"kekka.txt"から データの入力(読み込みを)している. /* File 読み込み */ #include <stdio.h> #include <stdlib.h> int main(void) { FILE *f; int i, …; If((f=fopen("kekka.txt","r"))== NULL){ printf(“オープン失敗\n"); exit(1); } for(i=0;i<=20;i++){ fscanf(f,"%d, %d",&x[i],&y[i]); printf("%d, %d \n", x[i], y[i]); fclose(f); return 0; 読み込み用のファイル (ここではkekka.txt )を開き, そのファイルをファイルポインタfで管理する. 戻り値がエラー(NULL)なら, 次のメッセージを出力してプログラムを終了 条件を満たす限り データ取り込みの操作を繰り返す
[課題 EX12-3] 実数(float)を、0から0. 01刻みで6. 28になるまで増加させ、その結果をファイル名「data1 [課題 EX12-3] 実数(float)を、0から0.01刻みで6.28になるまで増加させ、その結果をファイル名「data1.txt」のファイルに出力せよ →「EX12-3.c」 (ヒント) float x; で実数の変数を用意し、「for文」や「while文」を用いて繰り返し計算する。 「data1.txt」のファイル名で、書き込みモードでファイルをオープンし、「fprintf()」で結果を書き込む 最後に、ファイルをクローズするのを忘れないこと float型は7桁の精度なので、0.01を加えるごとに誤差が積算される。この誤差はこの問題では無視してよいです。
複数ファイルの同時使用 複数のファイルを同時にオープンして、同時に使用することができます どのファイルから読み込み、どのファイルに書き込むかは、ファイルポインタで指定します FILE *f1, *f2; /* ファイルポインタを2個用意 */ if((f1=fopen(”kekka1.txt”,”r”)==NULL){‥‥} /* f1をオープン */ if((f2=fopen(”kekka2.txt”,”w”)==NULL){‥‥} /* f2をオープン */ fscanf(f1,”%d”,&a); /* f1(ファイル名kekka1.txt)から読み込み */ fprintf(f2,”%d\n”,b); /* f2(ファイル名kekka2.txt)に書き込み */ fclose(f1); /* f1をクローズ */ fclose(f2); /* f2をクローズ */
[例題 EX12-4] 次の例を実行せよ.(EX12-4.c) if((f1=fopen("kekka.txt","r"))== NULL){ printf("オープン失敗\n"); exit(1);} if((f2=fopen("kekka1.txt", "w"))== NULL){ if((f3=fopen("kekka2.txt","w"))== NULL){ for(i=0;i<=20;i++){ fscanf(f1,"%d %d",&x[i],&y[i]); if(y[i]%2==0){ fprintf(f2,"%d %d\n",x[i] , y[i] ); } else{ fprintf(f3,"%d %d\n",x[i] , y[i] ); fclose(f1); fclose(f2); fclose(f3); return 0; このプログラムを実行すると「kekka.txt」というファイルからデータが読み込まれ、yが偶数なら「kekka1.txt」に、奇数なら「kekka2.txt」に書き込まれる /*--複数ファイルの読み書き ex13-3.c-*/ #include <stdio.h> #include <stdlib.h> int main(void) { FILE *f1, *f2, *f3; int i,x[100],y[100];
(ヒント) ファイルポインタを2個用意し、読み込みモード、書き込みモードでそれぞれオープンする [課題 EX12-5] 課題EX12-3で作成した「data1.txt」から実数xを読み込み、xに対するsin関数の値sin(x)を計算せよ。計算結果をファイル名「data2.txt」のファイルに出力せよ。ファイルには、「xの値 sin(x)の値」の順にスペースを挟んで出力せよ。結果のファイルをエクセルで読み込み、グラフとして表示せよ →「EX12-5.c」 (ヒント) ファイルポインタを2個用意し、読み込みモード、書き込みモードでそれぞれオープンする 「data1.txt」のデータ数は629個あるので、「for文」や「while文」で629回繰り返す* 最後に、ファイルをクローズするのを忘れないこと *上級者向け: データ数が未定の場合、ループ回数を固定することができない。この場合「C EOF」のキーワードでWEB検索してみよ。
(注) n個のデータの平均値,標準偏差はそれぞれ [課題 EX12-6] WEBからファイルdata10.txtをダウンロード(http://web.tuat.ac.jp/~muroo/computer-ex/data10.txt)し、data10.txtからN個のデータを読み込み,それらの平均値と標準偏差を計算せよ.その際,取り込むデータの数Nが N=10, (2) N=100, (3) N=200, (4) N=400 (5) N=800, (6) N=1200 (7)N=2400 のそれぞれについて計算し,比較せよ.また,N=2400の場合について,data10.txtをExcelで読み込み平均[=AVERAGE(A1:A…)]と標準偏差[=STDEV(A1:A…)] を計算し比較せよ.→EX12-6.c (注) n個のデータの平均値,標準偏差はそれぞれ と定義される.
[発展課題 EX12-7] data10.txtを読み込み,それらのデータのヒストグラムを計算せよ. その際,取り込むデータの数Nが N=10, (2) N=50, (3) N=200, (4) N=2400 のそれぞれについて計算し,比較せよ. 計算した結果について、エクセルでヒストグラムを作成せよ.→EX12-7.c (工学基礎実験参照) (ヒント) このデータxは0から19の間の整数で2400個ある。 そこで,ヒストグラムを作るにあたり,h[20]のような整数の配列データを用意し,読み込んだデータがxのとき h[x]=h[x]+1; (h[x]++;でもよい) のように加算すれば,最終的にh[0], h[1], … にxnew の出現頻度が格納される.(h[20]の初期化を忘れないこと)
☞ ヒストグラムの例
[発展課題 EX12-8] 区間[0,2π]で, 関数 を計算し,グラフに重ね書きをして示せ.
実習結果のレポート 3つのソースファイル「EX12-3.c」、「EX12-5.c」、「EX12-6.c」の中から少なくとも一つを添付ファイルにしてメールを送ってください。 宛先: muroo@cc.tuat.ac.jp 件名:コンピューター基礎実験12 本文:感想および一言