【C言語入門】fopenの使い方

こんにちは、もがちゃんです
今回は、fopenの使い方をサンプルソース付きで説明します

fopenは、ファイルから入力、または、ファイルへ出力する際に良く使用されます

fopen とともにセットで使用されるのが、fclose になります

fopenの構文

#include <stdio.h>
FILE *fopen(const char * restrict filename,const char * restrict mode);

fopenの説明

fopenは、filenameで指定された名前のファイルをオープンし
そのファイルに紐づいたファイルポインタを返却する関数です

fopen関数は、filenameが指す文字列を名前とするファイルをオープンし、そのファイルにストリームを結び付ける。

JISX3010 プログラム言語C
filename

オープンしたいファイル名の文字列を指定します

mode

ファイルをオープンする際の動作モードを文字列で指定します
動作モードには、以下の種類があります

mode動作
“r”テキストファイルを読み取りモードでオープンする
“w”テキストファイルを書き込みモードでオープンする
既にファイルが存在する場合
ファイルのサイズを0にする
“a”テキストファイルを追加モードでオープンする
既にファイルが存在する場合
ファイルの最後に追加するモードでオープンする
“rb”バイナリファイルを読み取りモードでオープンする
“wb”バイナリファイルを書き込みモードでオープンする
既にファイルが存在する場合
ファイルのサイズを0にする
“ab”バイナリファイルを追加モードでオープンする
既にファイルが存在する場合
ファイルの最後に追加するモードでオープンする
“r+”テキストファイルを更新(読み書き)
モードでオープンする
“w+”テキストファイルを更新モードでオープンする
既にファイルが存在する場合
ファイルのサイズを0にする
“a+”テキストファイルを更新モードでオープンする
既にファイルが存在する場合
ファイルの最後から更新するモードでオープンする
“r+b”
又は”rb+”
バイナリファイルを更新(読み書き)
モードでオープンする
“w+b”
又は”wb+”
バイナリファイルを更新モードでオープンする
既にファイルが存在する場合
ファイルのサイズを0にする
“a+b”
又は”ab+”
バイナリファイルを更新モードでオープンする
既にファイルが存在する場合
ファイルの最後から更新するモードでオープンする
mode一覧
返却値

filenameで指定された名前のファイルオープンに
成功した場合、ファイルに紐づいたファイルポインタを返します
失敗した場合、NULLポインタを返します

fopen関数は、オープンしたストリームを制御するオブジェクトへのポインタを返す。オープン操作が失敗した場合、空ポインタを返す。

JISX3010 プログラム言語C

fopenの使い方サンプル

テキストファイルをオープンする簡単なサンプルを紹介します

動作モード”r”

test1.txt
line1
line2
line3
line4
サンプルソースと実行結果
#include <stdio.h>
int main(int argc, char *argv[]) {
  // "r"モードで test1.txt ファイルをオープン
  FILE *fp = fopen("test1.txt","r");
  if(fp != NULL) {
    // ファイルオープンが成功したら
    char buffer[512];
    //1行ずつbufferに読み込み標準出力へ出力する
    while(fgets(buffer, 512, fp) != NULL) {
      printf("%s", buffer);
    }
    // ファイルをクローズする
    fclose(fp);
  }
}
動作モード"r"サンプルプログラムの動作結果
動作モード”r”サンプルプログラムの動作結果

動作モード”w”

実行前のtest1.txt
line1
line2
line3
line4
サンプルソースと実行結果
#include <stdio.h>

int main(int argc, char *argv[]) {
  // "w"モードで test1.txt ファイルをオープン
  FILE *wp = fopen("test1.txt","w");
  if(wp != NULL) {
    // ファイルオープンが成功したらファイルに出力
    fprintf(wp,"fprint line 1\n");
    fprintf(wp,"fprint line 2\n");
    fprintf(wp,"fprint line 3\n");
    fprintf(wp,"fprint line 4\n");
    // ファイルをクローズする
    fclose(wp);
  }
  /*************************/
  // "r"モードで test1.txt ファイルをオープン
  FILE *fp = fopen("test1.txt","r");
  if(fp != NULL) {
    // ファイルオープンが成功したら
    char buffer[512];
    //1行ずつbufferに読み込み標準出力へ出力する
    while(fgets(buffer, 512, fp) != NULL) {
      printf("%s", buffer);
    }
    // ファイルをクローズする
    fclose(fp);
  }
}
動作モード"w"サンプルプログラムの動作結果
動作モード”w”サンプルプログラムの動作結果

実行後のtest1.txt

fprint line 1
fprint line 2
fprint line 3
fprint line 4

動作モード”a”

実行前のtest1.txt
fprint line 1
fprint line 2
fprint line 3
fprint line 4

サンプルソースと実行結果
#include <stdio.h>

int main(int argc, char *argv[]) {
  // "a"モードで test1.txt ファイルをオープン
  FILE *wp = fopen("test1.txt","a");
  if(wp != NULL) {
    // ファイルオープンが成功したらファイルに出力
    fprintf(wp,"fprint line 5\n");
    fprintf(wp,"fprint line 6\n");
    fprintf(wp,"fprint line 7\n");
    fprintf(wp,"fprint line 8\n");
    // ファイルをクローズする
    fclose(wp);
  }
  /*************************/
  // "r"モードで test1.txt ファイルをオープン
  FILE *fp = fopen("test1.txt","r");
  if(fp != NULL) {
    // ファイルオープンが成功したら
    char buffer[512];
    //1行ずつbufferに読み込み標準出力へ出力する
    while(fgets(buffer, 512, fp) != NULL) {
      printf("%s", buffer);
    }
    // ファイルをクローズする
    fclose(fp);
  }
}
動作モード"a"サンプルプログラムの動作結果
動作モード”a”サンプルプログラムの動作結果

実行後のtest1.txt

fprint line 1
fprint line 2
fprint line 3
fprint line 4
fprint line 5
fprint line 6
fprint line 7
fprint line 8

動作モード”r+”

実行前のtest1.txt
fprint line 1
fprint line 2
fprint line 3
fprint line 4
fprint line 5
fprint line 6
fprint line 7
fprint line 8
サンプルソースと実行結果
#include <stdio.h>

int main(int argc, char *argv[]) {
  // "r+"モードで test1.txt ファイルをオープン
  FILE *wp = fopen("test1.txt","r+");
  if(wp != NULL) {
    // ファイルオープンが成功したらファイルに出力
    char buffer[512];
    // ファイルから入力
    fgets(buffer, 512, wp);
    printf("fgets -- %s", buffer);
    // ファイル中の位置を更新(現在位置に設定)
    fseek(wp, 0, SEEK_CUR);
    // ファイルへ出力
    fprintf(wp,"*** fprint line ***\n");
    // ファイルをクローズする
    fclose(wp);
  }
  /*************************/
  // "r"モードで test1.txt ファイルをオープン
  FILE *fp = fopen("test1.txt","r");
  if(fp != NULL) {
    // ファイルオープンが成功したら
    char buffer[512];
    //1行ずつbufferに読み込み標準出力へ出力する
    while(fgets(buffer, 512, fp) != NULL) {
      printf("%s", buffer);
    }
    // ファイルをクローズする
    fclose(fp);
  }
}
動作モード"r+"サンプルプログラムの動作結果
動作モード”r+”サンプルプログラムの動作結果

実行後のtest1.txt

fprint line 1
*** fprint line ***
line 3
fprint line 4
fprint line 5
fprint line 6
fprint line 7
fprint line 8

注意点

更新モードでオープン(mode実引数の2番目又は3番目の文字が’+’の場合)されたファイルに結び付けられたストリームに対しては,入力及び出力のいずれを行ってもよい。ただし,出力の後に入力を行う場合,この二つの操作の間にfflush関数又はファイル位置付け関数(fseek,fsetpos若しくはrewind)を呼び出さなければならない。ただし,入力操作がファイルの終わりに達した場合を除く。入力の後に出力を行う場合,この二つの操作の間にファイル位置付け関数を呼び出さなければならない。

JISX3010 プログラム言語C

動作モード”w+”

実行前のtest1.txt
fprint line 1
*** fprint line ***
line 3
fprint line 4
fprint line 5
fprint line 6
fprint line 7
fprint line 8
サンプルソースと実行結果
#include <stdio.h>

int main(int argc, char *argv[]) {
  // "w+"モードで test1.txt ファイルをオープン
  FILE *wp = fopen("test1.txt","w+");
  if(wp != NULL) {
    // ファイルオープンが成功したらファイルに出力
    char buffer[512];
    // ファイルへ出力
    fprintf(wp,"*** fprint 1 ***\n");
    // ファイル中の位置を更新(先頭に設定)
    fseek(wp, 0, SEEK_SET);
    // ファイルから入力
    fgets(buffer, 512, wp);
    printf("fgets -- %s", buffer);
    // ファイル中の位置を更新(現在位置に設定)
    fseek(wp, 0, SEEK_CUR);
    fprintf(wp,"*** fprint 2 ***\n");
    // ファイルをクローズする
    fclose(wp);
  }
  /*************************/
  // "r"モードで test1.txt ファイルをオープン
  FILE *fp = fopen("test1.txt","r");
  if(fp != NULL) {
    // ファイルオープンが成功したら
    char buffer[512];
    //1行ずつbufferに読み込み標準出力へ出力する
    while(fgets(buffer, 512, fp) != NULL) {
      printf("%s", buffer);
    }
    // ファイルをクローズする
    fclose(fp);
  }
}
動作モード"w+"サンプルプログラムの動作結果
動作モード”w+”サンプルプログラムの動作結果

実行後のtest1.txt

*** fprint 1 ***
*** fprint 2 ***

動作モード”a+”

実行前のtest1.txt
*** fprint 1 ***
*** fprint 2 ***

サンプルソースと実行結果
#include <stdio.h>

int main(int argc, char *argv[]) {
  // "a+"モードで test1.txt ファイルをオープン
  FILE *wp = fopen("test1.txt","a+");
  if(wp != NULL) {
    // ファイルオープンが成功したらファイルに出力
    char buffer[512];
    // ファイルへ出力
    fprintf(wp,"*** fprint 3 ***\n");
    // ファイル中の位置を更新(先頭に設定)
    fseek(wp, 0, SEEK_SET);
    // ファイルから入力
    fgets(buffer, 512, wp);
    printf("fgets -- %s", buffer);
    // ファイル中の位置を更新(現在位置に設定)
    fseek(wp, 0, SEEK_CUR);
    fprintf(wp,"*** fprint 4 ***\n");
    // ファイルをクローズする
    fclose(wp);
  }
  /*************************/
  // "r"モードで test1.txt ファイルをオープン
  FILE *fp = fopen("test1.txt","r");
  if(fp != NULL) {
    // ファイルオープンが成功したら
    char buffer[512];
    //1行ずつbufferに読み込み標準出力へ出力する
    while(fgets(buffer, 512, fp) != NULL) {
      printf("%s", buffer);
    }
    // ファイルをクローズする
    fclose(fp);
  }
}
動作モード"a+"サンプルプログラムの動作結果
動作モード”a+”サンプルプログラムの動作結果

実行後のtest1.txt

*** fprint 1 ***
*** fprint 2 ***
*** fprint 3 ***
*** fprint 4 ***

fopenのまとめ

modeに”w”を含む場合、ファイルが既に存在する場合は、ファイルの内容がクリアされる

modeに”a”を含む場合、ファイルが既に存在する場合は、ファイルの最後に追加される

modeに”+”を含む場合、入力も出力の操作も可能
ただし、入力後に出力、出力後に入力を行う場合は、ファイル位置付け関数(fseek,fsetpos若しくはrewind)の呼び出しが必要

modeに”b”を含む場合、バイナリファイルのオープンになる

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA