HIR-NET Home 運営者 オンラインソフト 運営者著書 CG HIR-NETリンク集
Tweet このエントリーをはてなブックマークに追加
C言語辞典

fopenエフ・オープン関数かんすう
fopen function

語源  fileファイオ openオゥプン(ファイル・オープン)
分類  C/C++標準ライブラリ/関数/入出力関数/ファイルアクセス関数
名称  ファイルオープン関数(file open function)
対義  fclose関数
類似  freopen関数
関連  NULLマクロ, feof関数, ferror関数
解説  fopen関数は、ファイルをオープンする関数です。ファイル名文字列 *fiilename… の名前を持つファイルをオープン・モード文字列 *mode… の方式でオープンし、ファイルとプログラムを結ぶストリームに結合します。オープンしたとき、ストリームが対話型装置を参照していない場合に限って、完全バッファリングされます。ストリームのエラーとファイルの終わり指示子は取り除かれます。

関数原型宣言ヘッダ  <stdio.h>
関数原型宣言例
NULL≠ストリーム
NULL=失敗         オープン・ファイル名文字列
↑                                 ↓
FILE *fopen(const char * restrict filename,
            const char * restrict mode);
                                   ↑
                       オープン・モード文字列
関数返却値
①ストリームを制御するオブジェクト(変数)へのポインタを返します。
②オープン操作が失敗したときは NULL(空ポインタ)を返します。

注意  処理系によっては共通の拡張として以下のオープン文字列に付加的な文字の列が続くことがあります。テキスト・ファイルやバイナリ・ファイル以外の対応付けが可能な処理系もあります。

【オープン・モード文字列 第1文字目】
r …… 読込(Read)モード:読込用にオープン。ファイルが存在しないか、読込不可能な場合はオープンは失敗します。fseek関数などによって、読込位置のファイル位置付けが可能です(ランダム・アクセス)。
w …… 書出(Write)モード:]書出用にオープン。ファイルが存在しない場合はファイルを生成します。ファイルが存在すればファイルの長さを 0 に切り詰めます。fseek関数などによって、書出位置のファイル位置付けが可能です(ランダム・アクセス)。
 既に出力したファイルの内容を上書することが出来るのはもちろん、まだファイルの存在しない位置にも書き出すことが出来ます。ただし、ファイルの存在しない位置に書き出した場合、その間のファイルの内容は不定です。
a …… 追加(Append)モード:既存ファイルの終わりに書き出すためにオープンするか、ファイルがなければ生成しオープンします。
 fseek関数などによってファイル位置付けをしても、書出は常に現在のファイルの終わりの位置に対して行われます。
 更新モード("a+")での fseek関数などによるファイル位置付けは読込のみ有効で、書出については無効で常に先頭になります。
 バイナリ・モード("ab")でオープンした場合、空文字のパディングをする処理系では、ストリームに対するファイル位置指示子を、書かれている最後のデータを越えて位置付することもあります。

【オープン・モード文字列 第2,3文字目】
b …… バイナリ(Binary)モード:テキスト・ファイルとしてではなく、バイナリ・ファイルとしてオープン。ftell関数の返却値はファイルの先頭からのバイト数となります。fseek関数により移動したい量だけ移動が可能です(ランダム・アクセス)。
 一方、テキスト・ストリームではファイルの先頭への移動, 終端への移動, ftell関数を呼び出した位置への移動のみが可能です。つまり、rewind, fgetpos, fsetpos関数は問題なく使用できます。
+ …… 更新モード:オープン時に対応するストリームに対して読込と書込の両方が可能。rwabの機能は複合します。ただし、処理系によっては更新モードが常にバイナリ・モードとなりえることが規定されています。従って、テキスト・ファイルについて同時に入出力するプログラムは規格厳密合致プログラムではありません。
 また、バッファの関係上、次のことに注意しなければなりません。書出に続く読込の前と、ファイルの終わりに達していない読込に続く書出の前には、fflush関数かファイル位置付け関数(fseek, fsetpos, rewind)の呼出が必要です。
 読込と書出の両方を行いたい場合で、既存ファイルがない場合に、ファイルの生成をしたい場合は、まず"r+"でオープンし、既存ファイルがなくオープンできなかったら、"w+"で生成オープンを試みるとよいです。
  FILE *sget=fopen(fn,"r+"); // 生成なし
  if(sget==NULL)
  {
    sget=fopen(fn,"w+"); // 生成あり
    if(sget==NULL)
    {

【オープン・モード文字列】○可能 ◎ランダム・アクセス □制限あり ▽注意が必要
"オープン・モード文字列" : モード読込書出移動生成切詰バイナリ
"r":テキスト・ファイル読込モード
"w":テキスト・ファイル書出モード あり
"a":テキスト・ファイル追加モード 追加
"rb":バイナリ・ファイル読込モード
"wb":バイナリ・ファイル書出モード あり
"ab":バイナリ・ファイル追加モード 追加
"r+":テキスト・ファイル読込,更新モード
"w+":テキスト・ファイル書出,更新モードあり
"a+":テキスト・ファイル追加,更新モード追加読込▽
又はバイナリ・ファイル追加,更新モード 追加読込▽
"r+b"
"rb+":バイナリ・ファイル読込,更新モード
"w+b"
"wb+":バイナリ・ファイル書出,更新モード あり
"a+b"
"ab+":バイナリ・ファイル追加,更新モード 追加読込▽



 プログラム例   

ファイル・オープンの基本
オープンしてクローズするプログラムです。
// fopen1.c

#include <stdio.h>  // FILE,NULL,fopen,fclose,printf
#include <stdlib.h> // EXIT_FAILURE,EXIT_SUCCESS,exit


int main(void)
{
  FILE *sget;
  sget=fopen("ファイル名","r"); // 読込

  if(sget==NULL)
  { // オープンチェック
    printf("fopen失敗\n");
    exit(EXIT_FAILURE);
  }

  //…

  fclose(sget); // クローズ

  return EXIT_SUCCESS;
} // main
実行結果  "ファイル名"が存在すればそのファイルをオープンしクローズ。存在しなれば「fopen失敗⏎」を出力します。

ランダム・アクセスによる書出
"w" でランダム・アクセスによる書出が可能です。
// fopen2.c

#include <stdio.h> // FILE,fopen,fclose,fprintf
#include <stdlib.h> // EXIT_SUCCESS


int main(void)
{
  FILE *sput=fopen("fopen.tes","w"); // 書出モード

  fprintf(sput,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  fseek(sput,10L,SEEK_SET); // 先頭から10バイト目に移動

  fprintf(sput,"xyz");
  rewind(sput);             // 先頭に移動
  fprintf(sput,"abc");
  fseek(sput,30L,SEEK_SET); // 先頭から30バイト目に移動
  fprintf(sput,"567890\n"); // まだ存在してない位置に出力できる
  fseek(sput,26L,SEEK_SET); // 先頭から26バイト目に移動
  fprintf(sput,"1234");

  fclose(sput);

  return EXIT_SUCCESS;
} // main
実行結果  出力されるファイルの内容は以下のようになります。
abcDEFGHIJxyzNOPQRSTUVWXYZ1234567890
                              ↑
                       fseekで移動
ランダム・アクセスによる読み書き
"r+" によりランダム・アクセスによる読み書きが可能であるが、"a" のモードでは常に追加となります。
// fopen3.c

#include <stdio.h> // FILE,fopen,fclose,fgetc,fprintf,fseek,rewind,printf
#include <stdlib.h> // EXIT_SUCCESS


int main(void)
{
  void fdisp(FILE *fs);
  FILE *fs=fopen("fopen.tes","w"); // 書出モード
  fprintf(fs,"ABCDEFGH");
  fclose(fs);

  fs=fopen("fopen.tes","r+"); // 読込・更新モード
  fdisp(fs);             // 先頭から表示
  fseek(fs,2L,SEEK_SET); // 先頭から2バイト目に移動
  fprintf(fs,"123");     // 上書き
  fclose(fs);

  fs=fopen("fopen.tes","a+"); // 追加・更新モード
  fdisp(fs);             // 先頭から表示
  fseek(fs,2L,SEEK_SET); // 先頭から2バイト目に移動しても
  fprintf(fs,"456");     // 追加となる
  fdisp(fs);             // 先頭から表示
  rewind(fs);
  fprintf(fs,"789");     // 先頭に移動しても追加となる
  fdisp(fs);             // 先頭から表示

  return EXIT_SUCCESS;
} // main



void fdisp(FILE *fs)
{
  rewind(fs); // 先頭に

  while(1)
  {
    int c=fgetc(fs);
    if(c==EOF)break;
    printf("|%c",c);
  } // while

  printf("|\n");
} // fdisp
実行結果  出力されるファイルの内容は以下のようになります。
|A|B|1|2|3|F|G|H|       …… 123が上書
|A|B|1|2|3|F|G|H|4|5|6| …… 456が追加
|A|B|1|2|3|F|G|H|4|5|6|7|8|9| …… 789が追加





HIR-NET Home 運営者 オンラインソフト 運営者著書 CG HIR-NETリンク集
◆リンクは、ご自由にお張りください。

Copyright © 1988-2017 Hirabayashi Masahide  プライバシーポリシー