PowerPoint版

プログラミング演習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をコンパイル・実行してみよう
今日学んだこと

ファイル入出力




標準入出力から・への入出力
ファイルとストリーム
ストリームへの入出力
コマンドラインからの入力
レポート課題


ファイル名を引数として与えると、そのファイ
ルの内容を端末に表示するプログラムmycatn.cを作れ.ただし、行の先頭に、行番号を表
示すること.$ ./mycat-n.exe llist.h
1: typedef struct _Node {
実行例:
2: char *contents;
3: struct _Node *next;
4: } *Node;
5:

ヒント:Sample12.c, Sample16.c.
レポート課題



締め切り:2005年1月25日一杯(日本時間で)
提出:メールで木村([email protected])まで.
感想などあると木村が喜びます