ファイルシステムというか、ファイル入出力の基礎。
fopen()
ファイルを開くとき、つまりファイルをストリームと結びつけるときには fopen() を使う。fopen() の一般的な形式は次のとおり。
FILE *fopen(char *ファイル名, char *モード);
本(「独習 C」)に習ってプロトタイプ風に書いてみた。FILE * は戻り値の型を示していて、FILE という構造体へのポインタだ。
fopen() をはじめ、ファイルシステム関連の関数は stdio.h を使う。FILE も stdio.h で定義されている。
モードは、書き込みか読み込みか、あるいはテキストかバイナリかなどを示す文字列(へのポインタ)だ。次のようなモードがある。
r | 読み込み用にテキストファイルを開く |
w | 書き込み用にテキストファイルを開く |
a | テキストファイルに追加する |
rb | 読み込み用にバイナリファイルを開く |
wb | 書き込み用にバイナリファイルを開く |
ab | バイナリファイルに追加する |
r+ | 読み込み/書き込み用にテキストファイルを開く |
w+ | 読み込み/書き込み用にテキストファイルを作成する |
a+ | 読み込み/書き込み用にテキストファイルに追加する。またはテキストファイルを作成する。 |
r+b | 読み込み/書き込み用にバイナリファイルを開く |
w+b | 読み込み/書き込み用にバイナリファイルを作成する |
a+b | 読み込み/書き込み用にバイナリファイルに追加する。またはバイナリファイルを作成する。 |
ファイルを開く操作が失敗すると、fopen() はヌルポインタを返す。stdio.h では NULL というマクロがヌルポインタとして定義されている。ファイルを開いた時には、それが成功したかどうかをチェックしなければいけない。
FILE *fp; if ((fp = fopen("myfile", "r")) == NULL) { printf("Channot open the file."); exit(1); }
fclose()
ストリームが不要になった時にはこれを閉じる必要がある。ストリーム(ファイル)を閉じるには fclose() を使う。
int fclose(FILE *ストリーム);
文字の読み込みと書き込み
文字の読み込みには fgetc()、書き込みには fputc() をつかう。
int fgetc(FILE *ストリーム); int fputc(int 文字, FILE *ストリーム);
fgetc() はストリームの次のバイトを unsigned char として読み込み、int として返す。エラーが起こったり、ファイルの終わりに達すると EOF を返す。fgetc() は int を返すけど、読み込んだ文字は下位バイトに含まれるので char に代入することもできる。
fputc() はストリームに「文字」の下位バイトを unsigned char の値として書き込む。「文字」は int と定義されているけど、char を渡しても問題ない。書き込みが成功すると書き込んだ文字を返し、失敗すると EOF を返す。
次のプログラムは、文字列をテキストファイル myfile に書き込み、いったん閉じたあと読み込み用に開きなおして、内容を表示する。
#include #include int main(void) { char str[80] = "This is a test for file system.\n"; FILE *fp; char ch, *p; /* open myfile to write */ if ((fp = fopen("myfile", "w")) == NULL) { printf("Channot open the file.\n"); exit(1); } /* write str. */ p = str; while (*p) { if (fputc(*p, fp) == EOF) { printf("Error.\n"); exit(1); } p++; } fclose(fp); /* open myfile to read */ if ((fp = fopen("myfile", "r")) == NULL) { printf("Channot open the file.\n"); exit(1); } /* read the file */ for ( ; ; ) { ch = fgetc(fp); if (ch == EOF) { break; } putchar(ch); } fclose(fp); return 0; }
実行結果:
takatoh@nightschool $ ./sample_9_2 This is a test for file system.
練習問題9.2
1. コマンドライン引数で指定したテキストファイルの内容を表示するプログラムを作成してください。
#include #include int main(int argc, char *argv[]) { FILE *fp; char ch; if (argc != 2) { printf("Usage: %s \n", argv[0]); exit(1); } if ((fp = fopen(argv[1], "r")) == NULL) { printf("Cannot open file: %s\n", argv[1]); exit(1); } while ((ch = fgetc(fp)) != EOF) { putchar(ch); } fclose(fp); return 0; }
takatoh@nightschool $ ./practice_9_2_1 Usage: ./practice_9_2_1 <textfile> takatoh@nightschool $ ./practice_9_2_1 myfile This is a test for file system.