5.ファイルの入出力
C言語では、ファイルを操作するのにFILE構造体のポインタを使用します。以下は指定したファイルの中身をコンソールに出力するサンプルプログラムです。
#include <stdio.h> int main(int argc,char *argv[]){ FILE *fp; char line[256]; if(argc!=2){ exit(1); } if((fp=fopen(argv[1],"r"))==NULL){ exit(1); } while(fgets(line,256,fp)!=NULL){ puts(line); } fclose(fp); return(0); }
5.1.main関数の引数
main関数は、int型とchar型のポインタ配列(ポインタを要素とする配列)を引数として取ることができます。 これらはプログラムの実行時に、コマンドラインで指定されたオプションを受け取るために用意されています。1つ目の引数には指定されたオプションの個数が、2つ目の引数にはオプションの値が順に格納されます。たとえば「sample.exe」というプログラムが以下のようにコンソールで実行された場合、
$ ./sample.exe test1 test2
argcには「3」、argv[1]には「test1」、argv[2]には「test2」という値が格納されます。argv[0]には「./sample.exe」という値が格納されており、どんな場合でもargcの値は1以上になるようになっています。サンプルプログラムでは、7行目でオプションの個数が1個であるかどうか判定しており、11行目で1つ目のオプションで指定されたファイルをオープンしています。
5.2.fopenとfclose
ファイル操作ではまず「fopen」関数でファイルを開き、その時に得るファイルポインタを通じてファイルを操作します。そして最後に「fclose」関数でファイルを閉じます。サンプルプログラムでは11行目で指定されたファイルを開き、19行目でファイルを閉じています。
fopen関数は2つの引数を取り、第1引数で開きたいファイルの名前、第2引数でファイルを開くときのモードを指定します。"r"は読み取りモードで開くことを示しています。"w"は上書き、"a"は追加書き込み、"r+"および"w+"は読み書きモードです。fopenはファイルのオープンに成功するとFILE構造体のポインタを返し、失敗した場合はNULLを返します。
fclose関数は引数で指定されたFILEポインタが示すファイルをクローズします。Cのプログラムは、終了時にオープンしているファイルがあれば自動的にクローズします。したがってfcloseを使用しなくてもプログラム上問題ありませんが、使用する方が望ましいです。
5.3.fgets
「fgets」はファイルから1行ずつ読み込む関数です。引数は3つで、1つ目が読み込んだ値を格納する変数、2つ目が読み込む値の最大文字数、3つ目が対象のファイルポインタです。fgetsはファイルから1行読み込むか最大文字数に達した場合に処理を終了し、指定された変数に読み込んだ値を格納します。また処理が終了すると同時に、読み込み地点を読み込んだ分だけ先に進めます。したがって繰り返しfgetsを実行すれば、ファイルの先頭から終了までを読み込んでいくことができます。またファイルの終了地点でfgetsはNULLを返すので、それと同時に繰り返し処理を終了すればよいです(15行目)。ファイルの読み込みに失敗した場合にも、fgetsはNULLを返します。
(実習課題)
以下のプログラムを作成しなさい。
- コマンドラインからプログラムに渡されるオプションは1つで、それはファイル名。
- 指定されるファイルの中には1行ごとに数字が書き込まれており、プログラムはその数字を読み込んでコンソールに表示する。
- 数字の最大桁数は4桁。
- 最後に「読み込んだ数字の合計」および「3の倍数である数の個数」「5の倍数である数の個数」を表示する
(実習課題)
以下のプログラムを作成しなさい。
- コマンドラインからプログラムに渡されるオプションは2つ。
- 1つ目のオプションで指定されたファイルの中身を、2つ目のオプションで指定されたファイルにコピーする。
- コピーの際、行の順番が逆になるようにする。つまり1つ目のファイルの先頭行が2つ目のファイルの最終行に、1つ目の最終行が2つ目の先頭行になるようにする。
- 1つ目のファイルは、最大10行で1行の文字数は最大256とする。
- (ヒント)いったんファイルの中身を2次元配列に格納してしまう。
- (ヒント)ファイルの書き込みには「fputs」か「fprintf」を用いる。
(実習課題)
以下のプログラムを作成しなさい。3章の課題の改良です。
- 10個の文字列を格納できる1つのchar型の変数(つまりchar型の2次元配列)を作成する。
- その変数にキーボードから入力された10個の文字列を格納する。
- キーボードからの入力文字列は最長63文字とする。
- 最後に、10個の文字列を順にコンソールに出力する。
- getsを使用せずに、fgetsを使用すること。
- (ヒント)標準入力を表すファイルポインタを使用する。