ファイル出力


ファイルを取り扱うには次の手順を踏みます。
  1. ファイルのオープン
  2. 読み書き
  3. ファイルのローズ
FILE *fopen(
            const char *filename,
            const char *mode                                                              
            );

が必要です。filenameには、フィアル名を指定します。modeには、オープンモードを指定します。

"r"
読み出し用にオープン。指定したファイルが存在いないとき、関数は失敗する。
"w"
書き込み用にオープン。指定したファイルがすでに存在するときは、これに上書きされる。指定したファイルが存在しない場合は、新規に作られる。
"a"
すでに存在するファイルに追加する。指定したファイルが存在しなければ新規に作成
"r+"
ファイル読込み•更新モード。ファイルが存在しないとき、関数は失敗する。
"w+"
読み出し•書き込みモードでオープン。ファイルが存在すると上書きされる。
"a+"
読み出し、追加•更新モード
"wb"
バイナリで書き込み
"rb"
バイナリで読込み
"ab"
バイナリで追加
さて、この関数の戻り値の型である「FILE *」とはなんでしょうか。これは、FILE構造体へのポインタです。FILE構造体は stdio.h の中で定義されています。興味がある人は、stdio.h の中をぞいてみてください。ここでは、ファイルポインタと呼ぶことにします。
関数が成功するとファイルポインタが返されます。以後このファイルポインタを使って読み書きすることになります。関数が失敗するとNULLが返されます。必ず戻り値をチェックしてから、次の作業に移りましょう。
ファイルをクローズするにはfclose関数を使います。
int fclose(
           FILE *stream                                                                   
           );
が必要です。引数には、openしたときのファイルポインタを指定します。関数が成功したときは0が返されます。関数が失敗したときは EOF が返されます(EOF を -1 と定義してあるコンパイラが多い)。

ファイルは fopen 関数で開き、fclose 関数で閉じる。

さて、オープンしたファイルに書込むにはどんな関数を使うのでしょうか。ファイル入出力に関係した多くの関数は「f」で始まる名前を持ちます。f はもちろん file の f です。毎度おなじみの printf 関数に f をつけて fprintf 関数とかいうのがあるのでしょうか。実はあります。
int fprintf(
            FILE *stream,
            const char *format [,
                                argument ]...                                             
            );
が必要です。最初の引数は、ファイルポインタです。あとは、printf関数と同じです。
では、text.txt というファイルを作って、その中に「初めてのファイル入出力です」と書込むプログラムを作ってみましょう。

ソースコード

源文件
  1|/* file01.c */                                                                        
  2|
  3|#include <stdio.h>
  4|
  5|int main(void)
  6|{
  7|  FILE *fp;
  8|  fp = fopen("text.txt", "w");
  9|
 10|  if(fp == NULL) {
 11|    perror("ファイルはオープンに失敗しました\n");
 12|    return -1;
 13|  } else {
 14|    printf("フィアルを正常にオープンしました\n");
 15|  }
 16|  fprintf(fp, "初めてのファイル入出力です。\n");
 17|
 18|  /* ファイルのクローズ */
 19|  if (fclose(fp) != 0){
 20|    perror("ファイルのクローズに失敗しました\n");
 21|  } else {
 22|    printf("ファイルを正常にクローズしました\n");
 23|  }
 24|  return 0;
 25|}

実行結果

フィアルを正常にオープンしました
ファイルを正常にクローズしました

# cat text.txt 
初めてのファイル入出力です。
では、もう少し実用なプログラムを作ってみましょう。ユーザーから氏名、電話番号の入力を受付 ファイルに書き込みます。



ソースコード

源文件
  1|/* file02.c */
  2|
  3|#include <stdio.h>
  4|#include <string.h>
  5|
  6|int mywrite(FILE *);
  7|
  8|int main(void)
  9|{
 10|  FILE *fp;
 11|  char filename[256];
 12|
 13|  printf("ファイル名(拡張子不要)---");
 14|  scanf("%s", filename);
 15|  strcat(filename, ".txt");
 16|
 17|  fp = fopen(filename, "a"); /* 追加モード*/
 18|  if(fp == NULL){                                                                     
 19|    perror("ファイルのオープンに失敗しました\n");
 20|    return -1;
 21|  }
 22|  while (!mywrite(fp));  /* この書き方に注意 */
 23|
 24|  fclose(fp);
 25|  return 0;
 26|}
 27|
 28|int mywrite(FILE *f)
 29|{
 30|  char name[16];
 31|  char tel[16];
 32|  char yesno[8];
 33|  char *format = "%-15s %-15s\n";
 34|
 35|  printf("氏名--");
 36|  scanf("%s", name);
 37|  printf("電話--");
 38|  scanf("%s", tel);                                                                   
 39|
 40|  printf(format, name, tel);
 41|  printf("このデータを書込みますか(y/n):");
 42|  scanf("%s", yesno);
 43|  if(strcmp(yesno, "Y") == 0 || strcmp(yesno, "y") == 0){
 44|    fprintf(f, format, name, tel);
 45|  }                                                                                   
 46|  printf("さらにデータを入力しますか(y/n):");
 47|  scanf("%s", yesno);
 48|  if(strcmp(yesno, "N") == 0 || strcmp(yesno, "n") == 0){
 49|    return -1;
 50|  }
 51|  return 0;
 52|}

実行結果

ファイル名(拡張子不要)---text 
氏名--河野 
電話--080-1234-5678
河野          080-1234-5678  
このデータを書込みますか(y/n):y
さらにデータを入力しますか(y/n):y
氏名--山田
電話--080-9999-0120
山田          080-9999-0120  
このデータを書込みますか(y/n):y
さらにデータを入力しますか(y/n):n

# cat text.txt 
河野          080-1234-5678  
山田          080-9999-0120  

さらに、この電話帳に追加することも可能です。再度、プログラムを起動します。そして、ファイル名に text を指定します。そうすると、今までの text.txt にデータが追加されています。

入出力には「ストリーム」という概念があります。ストリーム(stream)とは、「流れ」という意味です。つまり、情報の流れという意味です。情報の流れは、ファイルからファイルへと流れます。

キーボードや画面も広い意味でのファイルです。

fprintf 関数の第1引数は「FILE *stream」となっていましたね。

この関数を使って、画面に表示させることも可能です。第1引数に標準出力ファイルポインタを指定すればよいのです。
/* stdout.c */

#include <stdio.h>

int main(void)
{
  fprintf(stdout, "テストです\n");

  return 0;                                                                               
}
このプログラムを実行すると、画面に「テストです」と表示されます。「stdout」は標準出力のファイルポインタで、stdio.h の中で定義されています。

常に標準出力に出力する fprintf 版が、printf 関数であると考えられます。なお、標準入力はstdin, 標準エラーは stderr と定義されています。

Chapte9 @ C言語目録 @ HomeWork List @ 昭亮's Homepage