ファイルの入出力 芝浦工業大学情報工学科 青木義満 今回の講義内容 ファイル入出力 ファイルからのデータ読込み ファイルと配列 2 1
ファイルへのデータ書き込み ( 復習 ) ソースファイル名 :fileio1.c データをファイルに書き込み #include <stdio.h> int main(void) { ファイルポインタ宣言 int student_id = 100; char name[ ]= "morishima"; ファイルに書き込むデータ double tensu = 95.5; 100 morishima 95.5 fp = fopen("test.txt","w"); fprintf( fp, "%d n", student_id ); fprintf( fp, "%s n", name ); fprintf( fp, "%f n", tensu ); test.txt という名前でファイルをオープン ( 書き込み用 ) fprintf( fp, "%d %s %f n", student_id, name, tensu ); fprintf( fp, "%d t%s t%f n", student_id, name, tensu ); データをファイルに書き込み fclose(fp); ファイルを閉じる return(0); 3 ファイルからのデータの読込みの必要性 ファイルに格納されているデータを, プログラム中に読み込んで処理 ファイル ~ 成績表リスト 1 aoki 80.5 100 morishima 95.5 50 tokunaga 70.4 プログラム ~xxx.c int student_id[number]; char name[number][256]; double score[number]; 4 2
データの作成 ( 野球選手成績リスト ) ソースファイル名 :player1.c チーム名, 選手名, ホームラン数をファイルに書き込み #include <stdio.h> #define NUM 100 /* 最大 100 人までの選手データを扱う */ int main(void) { char team[num][256]; char name[num][256]; int hr[num]; int i; fp = fopen("player.txt","w"); /* キーボードから選手データを読込み */ for(i=0; i < 5; i++){ printf("input Players' Data n"); printf("team : "); scanf("%s", team[i]); printf("name : "); scanf("%s", name[i]); printf("homerun : "); scanf("%d", &hr[i]); for(i=0; i < 5; i++){ /* 読み込んだデータを画面表示 */ printf( "%s %s %d n", team[i], name[i], hr[i]); /* 読み込んだデータをファイルへ書き込み */ fprintf( fp, "%s %s %d n", team[i], name[i], hr[i]); fclose(fp); return(0); player.txt G Matsui 50 L Matsui 33 D Fukudome 20 5 ファイルからのデータの読み込み ファイルからデータを読み込む際の手順 ファイルを開く ( 読込みモードで ) 変数へのデータの読込み fscanf 関数等を使用 ファイルを閉じる 6 3
ファイルを開く ~ fopen 関数 データを読み込む対象の ファイル名 を指定 読み込みモードを指定 (2 つ目の引数に r を指定 ) 読み込みモードでファイルを開く操作 FILE *fp ( ファイルポインタ ) fp = fopen( file.txt, r ); ファイルを指定 file.txt ( ファイル ) ファイル名 読込みモード fp を介して, ファイルにアクセスが可能! 7 ファイルを開く際のモードの種類 ( テキストファイル ) モード r w a r+ w+ a+ 意味 読込み用にファイルを開く ファイルが存在しない場合や見つからない場合は失敗する 書き込み用にファイルを作成 ファイルが存在する場合はそのファイルの内容は破棄する 追加書き込みのために既存ファイルを開く ファイルが存在しない場合には作成する 読み書き用にファイルを開く ファイルは存在していなければならない 読み書き用にファイルを作成 ファイルが存在する場合には, そのファイルの内容は破棄する 読込みと追加の両方のモードでファイルを開く ファイルが存在しない場合は作成する 8 4
ファイルからのデータの読込み ~ fscanf 関数 scanf 関数 ( キーボードからのデータ入力 ) fscanf 関数 (file からのデータ入力 ) fscanf 関数の書式 scanf 関数 scanf( %d, &x); fscanf 関数 fscanf( fp, %d, &x ); データを読み込む対象ののファイル ( ポインタ ) fscanf fp = fopen( file.txt, r ); file.txt 100 プログラム中の変数 int x 9 fscanf 関数の使用例 実数データの読み込み ファイル :fscanf( fp, %lf, &x ); double x 文字列データの読込み 文字配列 1 つ : char name[256] fscanf( fp, %s, str ); 複数の文字配列 : char name[5][256] fscanf( fp, %s, str[i] ); 1 行に並んでいる複数の型のデータを読み込み fscanf( fp, %d %s %f, &student_id, name, &tensu ); file 1 aoki 80.5 char name[ 256] ; int student_id; double tensu; 10 5
ファイルを閉じる 使い終わったら, 後片付け ファイルを閉じる ファイルを開く時に指定したファイルポインタを指定 fclose(fp); 11 ファイルからのデータの読込み例題 ソースファイル名 :player2.c データをファイルから読み込み, 変数に格納, 表示 #include <stdio.h> #define NUM 100 int main(void) { char team[num][256]; char name[num][256]; int hr[num]; int i; for(i=0; i < 5; i++){ /* 読み込んだデータを画面表示 */ printf( "%s t%s t%d n", team[i], name[i], hr[i]); fclose(fp); return(0); fp = fopen("player.txt","r"); 読込みモードでファイルをオープン /* ファイルから選手データを読込み */ for(i=0; i < 5; i++){ fscanf(fp, "%s %s %d", team[i], name[i], &hr[i]); 12 6
入出力ファイル名の指定 これまでのプログラム 入出力ファイル名をプログラム中で指定 fp = fopen("player.txt","r"); キーボードからファイル名を指定できれば便利! ファイル名の指定 char filename[256]; printf( input filename : ); scanf( %s, filename ); fp = fopen( filename, r ); 13 入出力ファイル名の指定例題 ソースファイル名 :filename.c ファイル名を指定して開く #include <stdio.h> int main(void) { char filename[256]; printf( "Input file name : " ); scanf( "%s", filename ); fp = fopen(filename, "r"); ファイル名格納用変数 キーボードから入力した文字列を filename に格納 Filename でファイル名を指定して開く printf(" ファイル名は %s です ", filename); /* ファイルからのデータ読込み */ /* データ処理 */ return(0); 指定したファイルが存在しなかったら? 14 7
ファイルが開けるかどうかのチェック fopen 関数の仕様 fp = fopen(filename, "r"); ファイル filename が存在し, 開ける場合 fpにそのファイルを指定するファイルポインタを格納 (fpには, そのファイルを指定可能にするための何らかの値が入る ) ファイル filename が存在しない, 開けない場合 fpにはnull( 空 ) が代入される ファイルが開けるかどうかの判定 fp = fopen(filename, r ) == NULL == それ以外の値 if 文を使って判定 15 ファイルが開けるかどうかのチェック例題 ソースファイル名 : filecheck.c 指定したファイルが開けるかどうかを判定 #include <stdio.h> #include <stdlib.h> ヘッダーを追加 (exit 関数使用のため ) int main(void) { char filename[256]; printf( "Input file name : " ); scanf( "%s", filename ); ファイルが開けるかどうかの判定 if( (fp = fopen(filename, "r") ) == NULL ){ printf(" 指定したファイル %sは開けません n", filename); printf(" プログラムを終了します n"); exit(1); プログラムを終了 else{ printf( "file open 成功! n" ); printf( " ファイル名は %sです", filename ); /* ファイルからのデータ読込み, データ処理 */ fp=null, ファイルが開けなかった場合 fp!= NULL : ファイルが開けた場合 return(0); 16 8
演習課題 以下のようなサッカー選手のデータファイルをエディタ (emacs) で作成せよ そのファイルから, 選手名, アシスト数, ゴール数を読み込み, アシスト王, 得点王,MVP( アシスト + 得点が MAX) の選手を判定し, 画面に結果を表示するプログラムを作成せよ (kadai8.c) 名前アシストゴール 選手数は各自で決めて良い最大値を求める関数を自分で設計し 使用すること Takahara 7 20 Nakayama 5 13 Magron 2 8 Kazu 6 10 ファイル :player.txt 今日は 1 問のみ. 前回までの課題チェックを今日中に終えること!! 17 重要 中間テストについて 日時 :11 月 24 日 ( 月 )13:00~14:00 テスト終了後に ホームルーム実施 場所 :3401 教室 試験範囲 最初 ~ 第 6 回 ( 関数 ) まで 試験形式 筆記 すべて持ち込み不可 18 9
前回演習問題, 課題についての注意事項 演算の優先順位について radian = acos(naiseki/p1*p2); naiseki = x1*x2 + y1*y2; p1 = sqrt(x1*x1+y1*y1); p2 = sqrt(x2*x2+y2*y2); () を使って計算の優先順位を決める radian = acos(naiseki/(p1*p2)); naiseki p 1 * p 2 naiseki * p p 1 2 配列の要素数について int num; char name[num][128]; printf( 人数を入力してください : ); scanf( %d, &num); コンパイルエラー 重要配列の要素数に変数は使用できない 定数のみ使用可能 ( 直接数字を書くか,#defineで定数を定義するか) 必要なサイズの配列を動的に確保することも可能 alloc, malloc 関数 19 10