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