プログラミング演習 II 2005 年 1 月 19 日(第 9 回) 理学部数学科・木村巌
前回までの復習 共用体( union type ) 共用体( union type ) 列挙 (enumerated type ) 列挙 (enumerated type ) 構造体、構造体のポインタ、 typedef など を用いた、リンクトリストの実装例 構造体、構造体のポインタ、 typedef など を用いた、リンクトリストの実装例
今日学ぶこと ファイル入出力 ファイル入出力 標準入出力から・への入出力 標準入出力から・への入出力 ファイルとストリーム ファイルとストリーム ストリームへの入出力 ストリームへの入出力 コマンドラインからの入力 コマンドラインからの入力
ストリーム ストリーム:入出力できるモノを抽象化 した概念 ストリーム:入出力できるモノを抽象化 した概念 C 言語のプログラムでは、 C 言語のプログラムでは、 標準入力(キーボード) 標準入力(キーボード) 標準出力(画面) 標準出力(画面) 標準エラー出力(画面) 標準エラー出力(画面) 以上三つが、デフォルトで open されている 以上三つが、デフォルトで open されている
書式付き入出力 標準入力・出力への書式付き入出力 標準入力・出力への書式付き入出力 printf(), scanf() printf(), scanf() printf() の変換仕様:表 12-1 ( p. 388 ) printf() の変換仕様:表 12-1 ( p. 388 ) scanf() の変換仕様:表 12-2 ( p. 389 ) scanf() の変換仕様:表 12-2 ( p. 389 ) 出力幅、出力精度の指定 出力幅、出力精度の指定 Sample1.c から Sample4.c までを打ち込んで、 コンパイル・実行してみよう Sample1.c から Sample4.c までを打ち込んで、 コンパイル・実行してみよう
いろいろな入出力 scanf() は、空白の入った文字列を読み込め ない scanf() は、空白の入った文字列を読み込め ない gets() は使うべきではない gets() は使うべきではない 読み込んだデータの保存場所が、読み込んだ データよりも少ない場合、メモリが上書きさ れる 読み込んだデータの保存場所が、読み込んだ データよりも少ない場合、メモリが上書きさ れる fgets() を使う(後述) fgets() を使う(後述)
1 文字入出力 int getchar(void), void putchar(int) int getchar(void), void putchar(int) getchar() の返値は int. ( char ではない) getchar() の返値は int. ( char ではない) EOF ( End Of File )が、多くの環境で -1 という 値を割り当てられるが、 char だと符号なしな ので、 -1 を 255 と勘違いしてしまう EOF ( End Of File )が、多くの環境で -1 という 値を割り当てられるが、 char だと符号なしな ので、 -1 を 255 と勘違いしてしまう Sample7.c を入力して、コンパイル・実行 してみよう Sample7.c を入力して、コンパイル・実行 してみよう
ファイル入出力 ファイルをオープンする:ファイルとス トリームとを結びつける ファイルをオープンする:ファイルとス トリームとを結びつける ファイル(と結べつけられたストリー ム)を読み書きする ファイル(と結べつけられたストリー ム)を読み書きする ファイルをクローズする:ファイルとス トリームとの結びつきを解消する ファイルをクローズする:ファイルとス トリームとの結びつきを解消する
fopen(), fclose() ファイルを開く: FILE *fopen (char *fn, char *mode); ファイルを開く: FILE *fopen (char *fn, char *mode); fn で指定されたファイル名を持つファイル を、 mode で指定されたモードでオープン する fn で指定されたファイル名を持つファイル を、 mode で指定されたモードでオープン する FILE 型の構造体へのポインタが返値.こ れをファイルポインタという. FILE 型の構造体へのポインタが返値.こ れをファイルポインタという. ファイルポインタは、ストリームという概念 の実体 ファイルポインタは、ストリームという概念 の実体 ファイルモード:表 12-3 ( p. 402 )参照 ファイルモード:表 12-3 ( p. 402 )参照 Sample8.c をコンパイル・実行してみよう Sample8.c をコンパイル・実行してみよう
fopen(), fclose() の使い方 fopen() は、ファイルをオープンできなかっ た場合、 NULL を返す fopen() は、ファイルをオープンできなかっ た場合、 NULL を返す ファイルへの入出力が済んだら、ファイ ルを閉じる: fclose() ファイルへの入出力が済んだら、ファイ ルを閉じる: fclose()
ファイルへの出力 fputs(char *str, FILE *fp); fputs(char *str, FILE *fp); ファイルポインタ fp へ、 str を出力する ファイルポインタ fp へ、 str を出力する fprintf(FILE *fp, char *fmt, … ); fprintf(FILE *fp, char *fmt, … ); ファイルポインタ fp へ、書式指定 fmt で出 力する. printf() と同じ書式指定が可能 ファイルポインタ fp へ、書式指定 fmt で出 力する. printf() と同じ書式指定が可能
ファイルからの入力 ファイルからの 1 行入力 ファイルからの 1 行入力 fgets(char *buf, size_t n, FILE *fp); fgets(char *buf, size_t n, FILE *fp); ファイルポインタ fp から、 buf へ、 n byte 読み込む ファイルポインタ fp から、 buf へ、 n byte 読み込む 読み込むバイト数を指定できるので、バッファをあ ふれさせる心配がない( gets() の代わりに使う) 読み込むバイト数を指定できるので、バッファをあ ふれさせる心配がない( gets() の代わりに使う) 大量のデータを入力 大量のデータを入力 fscanf(FILE *fp, str *fmt, … ); fscanf(FILE *fp, str *fmt, … ); 書式指定 fmt に従って、ファイルポインタ fp から読み 込む 書式指定 fmt に従って、ファイルポインタ fp から読み 込む Sample12.c をコンパイル・実行してみよう Sample12.c をコンパイル・実行してみよう
バイナリファイルの読み書き テキストファイルとバイナリファイル テキストファイルとバイナリファイル テキストファイル:人間がそのまま読め、テ キストエディタ(メモ帳や秀丸など)で編集 できる テキストファイル:人間がそのまま読め、テ キストエディタ(メモ帳や秀丸など)で編集 できる バイナリファイル:それ以外 バイナリファイル:それ以外 バイナリファイルの利点 バイナリファイルの利点 計算機で処理しやすいデータのままでよい 計算機で処理しやすいデータのままでよい (人間に読みやすいように加工していない) (人間に読みやすいように加工していない) 処理が速い 処理が速い
バイナリファイル書き出し fopen() で、モードに b を加えると、バイナ リファイルとしてオープンする fopen() で、モードに b を加えると、バイナ リファイルとしてオープンする size_t fwrite (void *buf, size_t n, size_t c, FILE *fp); size_t fwrite (void *buf, size_t n, size_t c, FILE *fp); buf のデータを、 n byte 分、 c 回、ファイル ポインタ fp へ書き出す buf のデータを、 n byte 分、 c 回、ファイル ポインタ fp へ書き出す Sample13.c をコンパイル・実行してみよう Sample13.c をコンパイル・実行してみよう
バイナリファイルの読み込み size_t fread (void *buf, size_t n, size_t c, FILE *fp); size_t fread (void *buf, size_t n, size_t c, FILE *fp); ファイルポインタ fp から、 n byte, c 回、 buf へ読み込む ファイルポインタ fp から、 n byte, c 回、 buf へ読み込む Sample14.c を入力し、コンパイル・実行し てみよう Sample14.c を入力し、コンパイル・実行し てみよう
ランダムアクセス シーケンシャルアクセス( sequential access ) シーケンシャルアクセス( sequential access ) ファイルの先頭から順番に、データの読み書 きを行う ファイルの先頭から順番に、データの読み書 きを行う ランダムアクセス( random access ) ランダムアクセス( random access ) ファイルの任意の場所について、データの読 み書きを行う ファイルの任意の場所について、データの読 み書きを行う どの場所から移動を始めるか どの場所から移動を始めるか 現在の位置はどこか(ファイルポジション) 現在の位置はどこか(ファイルポジション)
ランダムアクセス int fseek(FILE *fp, size_t n, int WHENCE); int fseek(FILE *fp, size_t n, int WHENCE); ファイルポインタ fp のファイルの、 WHENCE で指定される位置から、 n バイト移動する ファイルポインタ fp のファイルの、 WHENCE で指定される位置から、 n バイト移動する WHENCE の部分は、 SEEK_SET, SEEK_CUR, SEEK_END のいずれか.意味は、教科書 p. 417 の表を見よ WHENCE の部分は、 SEEK_SET, SEEK_CUR, SEEK_END のいずれか.意味は、教科書 p. 417 の表を見よ
ランダムアクセスしてファイルを 読む size_t fread(void *BUF, size_t SIZE, size_t COUNT, FILE *FP); size_t fread(void *BUF, size_t SIZE, size_t COUNT, FILE *FP); ファイルポインタ FP のファイルから、 BUF に、 SIZE バイト、 COUNT 回読み込む ファイルポインタ FP のファイルから、 BUF に、 SIZE バイト、 COUNT 回読み込む Sample15.c をコンパイル・実行してみよう Sample15.c をコンパイル・実行してみよう
コマンドライン引数を使う int main (int ac, char *av[]) と main() 関数を宣 言する int main (int ac, char *av[]) と main() 関数を宣 言する プログラムの引数(起動時に指定された 値)を、 av という配列を使って受け取るこ とが出来る プログラムの引数(起動時に指定された 値)を、 av という配列を使って受け取るこ とが出来る ac は、引数の数 ac は、引数の数 av は、文字列の配列(それぞれが引数) av は、文字列の配列(それぞれが引数) av[0] は、プログラムの名前が入っている av[0] は、プログラムの名前が入っている
簡単な例 #include #include int main (int ac, char *av[]) { printf ( “ ac = %d, av[0] = %s, av[1] = %s.\n ”, ac, av[0], av[1]); return 0; } 上記を入力( Sample.c )し、コンパイル・実行してみよ う 上記を入力( Sample.c )し、コンパイル・実行してみよ う./Sample abc def./Sample abc def のように実行してみよ のように実行してみよ
コマンドライン引数 コマンドライン引数の使い道 コマンドライン引数の使い道 プログラムに、処理すべきファイルを指定す る プログラムに、処理すべきファイルを指定す る 与える引数によって、挙動を変える 与える引数によって、挙動を変える Sample16.c をコンパイル・実行してみよう Sample16.c をコンパイル・実行してみよう
今日学んだこと ファイル入出力 ファイル入出力 標準入出力から・への入出力 標準入出力から・への入出力 ファイルとストリーム ファイルとストリーム ストリームへの入出力 ストリームへの入出力 コマンドラインからの入力 コマンドラインからの入力
レポート課題 ファイル名を引数として与えると、その ファイルの内容を端末に表示するプログ ラム mycat-n.c を作れ.ただし、行の先頭に、 行番号を表示すること. ファイル名を引数として与えると、その ファイルの内容を端末に表示するプログ ラム mycat-n.c を作れ.ただし、行の先頭に、 行番号を表示すること. 実行例: 実行例: ヒント: Sample12.c, Sample16.c. ヒント: Sample12.c, Sample16.c. $./mycat-n.exe llist.h 1: typedef struct _Node { 2: char *contents; 3: struct _Node *next; 4: } *Node; 5:
レポート課題 締め切り: 2005 年 1 月 25 日一杯(日本時間 で) 締め切り: 2005 年 1 月 25 日一杯(日本時間 で) 提出:メールで木村( u.ac.jp )まで. 提出:メールで木村( u.ac.jp )まで. u.ac.jp u.ac.jp 感想などあると木村が喜びます 感想などあると木村が喜びます