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