C プログラミング Ⅱ の基礎
とは ファイルへデータを書き込んだり ( 出力 ), ファイルからデータを読み込んだり ( 入力 ) する C 言語では キーボードからの入力 画面への出力と同じようなコードで 処理を実現できる プログラム 入力 出力 ファイル 出力 入力 2
入出力の基本 ストリーム プログラム上で様々な装置への入出力を行う機構様々な入出力装置を統一的な方法で扱うことができる ハードディスクなどではファイルデータによって入出力が行われる 更新 ファイル fclose 書き込み ファイル ストリーム プログラム 読み込み fopen におけるストリームの概念 3
の基本 処理の順序 1 ファイルのオープン 入出力に使われるストリームとファイルとを結びつける 2 ファイルを読み書きする FILE *fp; fp = fopen("test1.txt", "w"); if(fp == NULL) printf(" ファイルをオープンできません n"); return 1; else printf(" ファイルをオープン n"); 3 ファイルのクローズ ストリームとファイルとを切り離す /* ファイルの読み書き */ fclose(fp); printf( ファイルをクローズ n"); return 0; 4
ファイルポインタの宣言 ファイルポインタ 現在, ファイルのどこを読み書きしているのかを指し示す ( 管理する ) ためのポインタ ファイルに接続するときには必ず必要 ファイルポインタの宣言 FILE * ポインタ名 ; FILE *fp; FILE *fp1, *fp2; 複数のファイルを扱いたい場合には複数のファイルポインタを宣言する 5
ファイルのオープン ( ファイルへの接続 ) ファイルに接続する ( ファイルをオープンする ) ファイルオープンの方法 ファイルポインタ = fopen( " ファイル名 ", " オープンモード " ); fopen 関数の戻り値 ファイルのオープンが何らかの原因で失敗した場合, [NULL] ( ヌル ) を返す. if 文を使用してファイルのオープンに成功したか失敗したかを判断し, 失敗したときの処理を書いておくことが望ましい 6
ファイルのオープンモード 下記の表は fopen 命令のモードを示したものである. 用途に対応したモードを設定する必要がある. モード意味詳細 r 読み込みモード ファイルを読み込み用で接続する. ファイルからデータの読み込みが可能. w 書き込みモード ファイルを書き込み用で接続する. ファイルへのデータの書き込みが可能. a 追記モード現在, 存在するファイルにデータの追記を行う. 7
ファイルオープン処理の例 FILE *fp; char filename[21] = "test2.txt"; if((fp = fopen("test1.txt", "w")) == NULL ) printf(" ファイルをオープンできません n"); return 1; ファイル test1.txt を書き込みモードでオープン同時にオープンに失敗したとき, プログラム実行を終了するようにしている if((fp = fopen(filename, "r")) == NULL) printf(" ファイルをオープンできません n"); return 1; 文字列 filename[] に格納されているファイル名のファイルを読み込みモードでオープン 8
ファイルのクローズ ( ファイルの切断 ) ファイルを切断する ( ファイルをクローズ する ) ファイルクローズの方法 fclose( ファイルポインタ ); FILE *fp; if((fp = fopen("test1.txt", "r")) == NULL ) printf(" ファイルをオープンできません n"); return 1; fopen 文で接続したストリームは関数の終了時 ( プログラム実行終了時 ) に fclose(fp); fclose 文で必ず切断することが望ましい 9
ファイルへの出力 ファイルへの書き込み ファイルへデータなどを書き込むには, 以下の 3 つの命令文 ( ファイル出力関数 ) がある 37 値 "Fukuoka" fprintf 文 fputc 文 fputs 文 書き込み ストリーム 文字列 "Fukuoka" 15 21.5 文字列メンバ 値メンバ 1 値メンバ 2 構造体 実際には, ストリームを介してファイルに書き込んでいる 10
ファイルへの書式付出力 fprintf 関数によるファイルへの書式付出力 ファイルへの書式付出力 fprintf( ファイルポインタ, " 書式付文字列 ", 引数 1, 引数 2,, 引数 n); int a = 10; double b = 3.1415926535; FILE *fp; fp = fopen("test.txt", "w"); fprintf(fp, "a = %d b = %4.2lf n", a, b); fclose(fp); 11
ファイルへの文字列出力 fputs 関数によるファイルへの文字列出力 文字列のみを出力する ( 変数の値などは出力できない ) ファイルへの文字列出力 fputs( " 文字列 ", ファイルポインタ ); FILE *fp; fp = fopen("string.txt", "w"); fputs("hello World n", fp); fclose(fp); 12
ファイルへの 1 文字出力 fputc 関数によるファイルへの 1 文字出力 文字データ (char 型データ )1 つを出力する ファイルへの 1 文字出力 fputc( char 型変数, ファイルポインタ ); char ch = 'A'; FILE *fp; fp = fopen("character.txt", "w"); fputc(ch, fp); fputc(' n', fp); fputc('z', fp); fputc(' n', fp); fclose(fp); 13
例 ) FILE *fp; int x = 20, y = 5; fp = fopen("test.txt", "w"); fprintf(fp, "x:%d y:%d n", x, y); fprintf(fp, " 和 :%d n", x + y); fprintf(fp, " 差 :%d n", x - y); fprintf(fp, " 積 :%d n", x * y); fprintf(fp, " 商 :%d n", x / y); 演算結果の書き込み fclose(fp); return 0; 14
ファイルからの入力 ファイルからの読み込み ファイルからデータなどを読み込むには, 以下の 3 つの命令文 ( ファイル入力関数 ) がある 37 ストリーム 読み込み fscanf 文 fgetc 文 fgets 文 値 "Fukuoka" 実際には, ファイルからストリームを介してデータを読み込んでいる 文字列 15
ファイルからの書式付入力 fscanf 関数によるファイルからの書式付入力 ファイルからの書式付入力 fscanf( ファイルポインタ, " 変換指定 ", 引数 1 のアドレス, ); int a; double b; FILE *fp = fopen("test.txt", "r"); fscanf(fp, "%d %lf", &a, &b); printf("a = %d b = %4.2 n", a, b); fclose(fp); 実行結果 a = 10 b = 3.14 16
ファイルからの文字列入力 fgets 関数によるファイルからの文字列入力 1 行分 ( 改行まで, もしくは最大文字数 ) の文字列を入力 ファイルへの文字列出力 fgets( 文字列 (char 型配列 ), 最大文字数 +1, ファイルポインタ ); Worldの次の改行文字まで 読み込んでいるので行が空いている char str[16]; FILE *fp = fopen("string2.txt", "r"); fgets(str, 15, fp); printf("1 行目 :%s n", str); fgets(str, 15, fp); printf("2 行目 :%s n", str); 実行結果 fclose(fp); return 0; 14 文字分 (+NULL 文字 ) しか入力されない 1 行目 :Hello World 2 行目 :Good Morning E 17
ファイルからの 1 文字入力 fgetc 関数によるファイルへの 1 文字出力 文字データ (char 型データ )1 つを入力する ファイルからの 1 文字入力 文字型変数 = fgetc( ファイルポインタ ); int i; char str[6]; FILE *fp = fopen("character2.txt", "r"); for(i = 0; i < 5; i++) str[i] = fgetc(fp); str[5] = NULL; printf("%s n", str); 1 文字ずつ入力して文字列に格納 実行結果 Hello 18
例 ) ファイル読み込み FILE *fp = fopen("test.txt", "r");; double x, y, z; fscanf(fp, "%lf", &x); fscanf(fp, "%lf", &y); fscanf(fp, "%lf", &z); 読み込み test.txt printf("x:%.2f y:%.2f z:%.2f n", x, y, z); fclose(fp); return 0; 実行結果 19
ファイルの読み込みとファイル走査 ファイル入力処理は, ファイル上を走査することにより読み込んでいる. 通常は左上から右下に向かって走査を行う. abcdef abcdef abcdef EOF 20
ファイルの読み込みとファイル走査 ファイルが終了すると fscanf 関数は [EOF](End Of File) を返す. fgets 関数は [NULL] を返す. ファイルに書かれているデータの数がわからない場合, それぞれの関数の戻り値を利用して入力処理を終了させる 例 1)fscanf 文と while 文の組み合わせ i = 0; while((fscanf(fp,"%d",&x[i]))!= EOF) i++; 例 2)fgets 文と while 文の組み合わせ char str[257]; while(fgets(str, 256, fp)!= NULL) printf("%s", str); printf(" n"); 21
ファイルからの文字列の読み込み fscanf 関数によるファイルからの文字列の読み込み fscanf 関数は空白文字, 改行文字は無視する int i; char str[6]; FILE *fp = fopen("alphtext.txt", "r"); alphtext.txt ABC DEF GHI JKL MNO PQR fscanf(fp, "%s", str); printf("%s n", str); fscanf(fp, "%s", str); printf("%s n", str); fscanf(fp, "%s", str); printf("%s n", str); 1 2 3 実行結果 ABC DEF GHI 2 の実行結果 ABC の後ろの空白文字は無視して DEF を読み込んでいる 3 の実行結果 DEF の後ろの改行は無視して GHI を読み込んでいる 22
ファイルからの文字列の読み込み fgets 関数によるファイルからの文字列の読み込み fgets 関数は空白文字, 改行文字は1 文字として読み込む int i; char str[6]; 最大 3 文字または改行まで読み込む FILE *fp = fopen("alphtext.txt", "r"); alphtext.txt ABC DEF GHI JKL MNO PQR 1 の実行結果 ABC の 3 文字まで読み込んでいる fgets(str, 4, fp); printf("%s n", str); fgets(str, 4, fp); printf("%s n", str); fgets(str, 4, fp); printf("%s n", str); 1 2 3 実行結果 ABC DE F 2 の実行結果空白文字も 1 文字とするので DE の 3 文字を読み込んでいる 3 の実行結果 F と改行文字の 2 文字を読み込んでいる改行まで読み込むので次の行の G は読み込まない 23