第3回 プログラミング応用
目的
ファイル入出力
1.ファイルの概念
2.ファイルの読み込み
3.ファイルの書き込み
ファイルの概念
CPUが外部とデータをやり取りするための媒介
入力装置
CPU
内部記憶装置
キーボード
出力装置
ディスプレイ
外部記憶装置
ハードディスク
CD-ROM
演算、判断
ファイル
printf関数やscanf関数でもうすでにファイルのやり取りの基本は学んでいる 00 30 42 23 43 10 21 95 21 64 02 83 47 39 85 20 83 70 32 94 21 18 04 62 32 42 53 74 26 84 16 38 ハードディスクの中身 #include <stdio.h> int main() { int det,A[2][2]; A[0][0] = 2; A[0][1] = 1; A[1][0] = 4; A[1][1] = 3; det = /* 行列式の計算を書く */ printf("|A| = %d¥n", det); return 0; } test.c ファイルを読むには 保存場所、フォーマットなど ファイルを作るには 空きのある場所 ある程度OSが面倒見てくれる OS、機械語プログラムファイルポインタに対し て読み書き処理を行う (fprintf, fscanf関数等) ・ファイルポインタを取得 ・読み書きモードの指定 (fopen関数) ファイルポインタを開放して、ファ イル他から使えるようにする (fclose関数)
C言語でのファイル操作の流れ
ファイルのオープン ファイルの読み書き処理 ファイルのクローズ 開いたファイルは必ず閉じる printf関数、scanf関数と同じ使い方 ファイルポインタはファイルに関する様々な情 報をまとめて入れておく変数。FILE *fp; FILE型変数の宣言、大文字でFILE、ファイル情報を入れておく箱
変数宣言部分
ファイルへのオープン
同時に複数個のファイルを操作したいときは複数のファイルポインタを宣言しておく 宣言時には変数名の前に必ず*(アスタリスク)を付ける fp=fopen(“ファイル名”,”モード”); 必ずファイルポインタ変数への代入文の形で書く命令文部分 (fopen関数)
ファイルポインタには現在ファイル中のどこを読んでいるかの情報も入っている。 ファイルが正しくオープンできたときfpにファイルポインタが入る 読み込みのとき r モードには 、書き込みのとき w の文字を指定 操作したいファイルとファイルポインタは1対1に対応するファイルへの書き込み
今まで使っていたprinf文の表記と類似
ファイルポインタ
を指定して、書き込むファイルを指定する
fprintf(ファイルポインタ,“出力文字列や変換文字“,変数名1,・ ・ ・); ・変換文字と代入する変数のデータ型は一致させる ・第三引数以降は数値を指定する.変数で表される数値でもよい ・書き込みモードで開かれたファイルに対して使用 ファイルへの書き込みファイルのクローズ
fclose(ファイルポインタ); ・開いたファイルは必ず閉じる演習3-1
#include <stdio.h>
int main() {
FILE *fp; /* ファイルポインタの宣言 */
fp=fopen(“test.txt”,”w”); /* ファイルを書き込みモードで開く */
fprintf(fp,”This is test. n”); /* 開いたファイルに文字を出力する */
fclose(fp); /* ファイルを閉じる */ return 0; } 1.実行してtest.txtというファイルが作られていることを確認せよ. 2.ファイル名を変えたり,出力する文字を変えたりして期待通りの結果になるか確認せよ 3.data.txt というファイル名でfor文を用いて10行2列の数字データを出力してみよ (答えは最後のスライド) output.c >ls ディレクトリ内容表示コマンド >cat ファイル名 ファイル内容表示コマンド
数値データファイルの読み込み
fscanf(ファイルポインタ,“変換文字“, &変数名1, ・ ・ ・) ・変換文字(%dとか%f等)と代入する変数のデータ型は一致させる ・fscanfでも変数名の前に & をつける. ・読み込みモードで開かれたファイルに対して使用 ファイルからの読み込み for(i=0;i<7;i++){scanf(“%d”,&a[i]);} キーボードからfor(i=0;i<7;i++){fscanf(fp,“%d”,&a[i]);} ファイルポインタ fp
hensuu
a[
0
] a[
1
] a[
2
]
a[
3
] a[
4
]
a[
hensuu
5
]
a[
6
]
fp=fopen(“test.dat”,”r”); for(i=0;i<7;i++){ fscanf(fp,“%d”,&a[i]); } 1 20 31 4 52 6 78 test.dat fscanf関数はファイル中の数値データをスペースや改行を区切りとして指定個数読み込む。 読み込む順番は左右、その行が終われば,次行の一番左から右に順に読まれる。 fscanf関数が読んだ最後の位置はファイルポインタが記憶している。 同じファイルを続けてfscanf関数で読めば、続きの場所から読み込まれる。 一旦開いたファイルは順番を飛ばしたり、反対方向に戻って読むことはできない。fscanf関数の注意点
ひとかたまりの数値を1個だけ読みこんで、整数として代入 数値データファイル演習3-2
ファイルからNUM個の数値データを読み込んで、端末画面に表示させるプログラム #include <stdio.h> #define NUM 10 int main() { FILE *fp; ファイルポインタの宣言int i,data[NUM]; 配列変数dataの定義
fp=fopen(“data.txt”,”r”); data.txtを読み込みモードで開く for(i=0;i<NUM;i++) { 中カッコ内をNUM回繰り返す
fscanf(fp,”%d”,&data[i]); 配列変数dataのi番目の要素にファイルから } 読み込んだ数値データを順次代入していく fclose(fp);
for(i=0;i<NUM;i++) { 中カッコ内をNUM回繰り返す
printf(”%d n”,data[i]); 配列変数dataの要素を出力して改行する
} return 0; } 1.演習3-1で作った数値データファイルがあることを確認した後,これを実行してみよ 2.読み込むデータの数を増やしてみよ,20以上を指定するとどうなるか確認せよ 3.存在しないファイル名を指定するとどうなるか確認せよ input.c
ファイルオープンのエラー処理
ファイルの読み書き関数は取得したファイルポインタに対して行う もしファイルポインタを正しく取得できなければ、ファイルの読み書き関数はハードディスク の間違った場所を読んだり、書き込んだりしてしまい他のファイルが損傷する恐れがある ファイルポインタが正しく取得できない(読み込みモードでファイルが存在しない)とき fopen関数はNULLという値(定数)を返すようになっている #include <stdio.h> int main() { FILE *fp; ファイルポインタの宣言 ……… fp=fopen(“test.txt”,”r”); test.txtを読み込みモードで開きファイルポインタを取得 if (fp==NULL){ test.txtが存在しないときprintf(“Can’t open file n”); メッセージを表示
return 1; 強制的にプログラムを終了する。
}
………
#include <stdio.h> # define NUM 10 int main() {
FILE *fpi,*fpo; /* 読み込み、書き込み用ファイルポインタの宣言 */
int i,data[NUM]; /* カウンタ変数i,得点データ用配列変数dataを定義 */
float ave,sum=0; /* 総得点用の変数sum, 平均値用の変数aveを宣言 */ fpi=fopen(“input.txt”,”r”);
if (fpi==NULL){ /* input.txtが存在しないときの処理 */
printf(“Can’t open file n”); /* メッセージを表示 */
return 1; /* 強制的にプログラムを終了する。 */
}
for(i=0;i<NUM;i++){fscanf(fpi,”%d”,&data[i]);}
for(i=0;i<NUM;i++){sum=sum+data[i];} /* 変数sumに配列data[i]の値を加えていく*/
ave=sum/NUM; /* 総得点sumを人数NUMで割って平均値aveを計算 */
fpo=fopen(“output.txt”,”w”); /* output.txtを書き込みモードで開く */
for(i=0;i<NUM;i++){
fprintf(fpo,”%d %d %f n”,i,data[i],(data[i]-ave)); } fclose(fpi); fclose(fpo); } input.txtから得点データをNUM人分読み、配列変数data[]に代入する部分をfor 文,fscanf関数を使って書く ここでNUM人分のデータ番号と、得点、(得点データ-平均値)をファイルに出力 する部分をfor文、fprintf関数を使って書く 10人以上の得点データ(適当に考えてよい)が入ったInput.txtという数値データファイルを emacsで作成し、プログラムで読み込む。その後、得点の平均値を計算する。 さらに、 output.txtにデータ番号、その得点、(得点-平均値)を出力せよ kadai3_sample.c