こんにちは、もがちゃんです
今回は、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
オープンしたいファイル名の文字列を指定します
ファイルをオープンする際の動作モードを文字列で指定します
動作モードには、以下の種類があります
mode | 動作 |
---|---|
“r” | テキストファイルを読み取りモードでオープンする |
“w” | テキストファイルを書き込みモードでオープンする 既にファイルが存在する場合 ファイルのサイズを0にする |
“a” | テキストファイルを追加モードでオープンする 既にファイルが存在する場合 ファイルの最後に追加するモードでオープンする |
“rb” | バイナリファイルを読み取りモードでオープンする |
“wb” | バイナリファイルを書き込みモードでオープンする 既にファイルが存在する場合 ファイルのサイズを0にする |
“ab” | バイナリファイルを追加モードでオープンする 既にファイルが存在する場合 ファイルの最後に追加するモードでオープンする |
“r+” | テキストファイルを更新(読み書き) モードでオープンする |
“w+” | テキストファイルを更新モードでオープンする 既にファイルが存在する場合 ファイルのサイズを0にする |
“a+” | テキストファイルを更新モードでオープンする 既にファイルが存在する場合 ファイルの最後から更新するモードでオープンする |
“r+b” 又は”rb+” | バイナリファイルを更新(読み書き) モードでオープンする |
“w+b” 又は”wb+” | バイナリファイルを更新モードでオープンする 既にファイルが存在する場合 ファイルのサイズを0にする |
“a+b” 又は”ab+” | バイナリファイルを更新モードでオープンする 既にファイルが存在する場合 ファイルの最後から更新するモードでオープンする |
filenameで指定された名前のファイルオープンに
成功した場合、ファイルに紐づいたファイルポインタを返します
失敗した場合、NULLポインタを返します
fopen関数は、オープンしたストリームを制御するオブジェクトへのポインタを返す。オープン操作が失敗した場合、空ポインタを返す。
JISX3010 プログラム言語C
fopenの使い方サンプル
テキストファイルをオープンする簡単なサンプルを紹介します
動作モード”r”
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);
}
}
動作モード”w”
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);
}
}
実行後のtest1.txt
fprint line 1
fprint line 2
fprint line 3
fprint line 4
動作モード”a”
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);
}
}
実行後の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+”
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);
}
}
実行後の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+”
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);
}
}
実行後のtest1.txt
*** fprint 1 ***
*** fprint 2 ***
動作モード”a+”
*** 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);
}
}
実行後のtest1.txt
*** fprint 1 ***
*** fprint 2 ***
*** fprint 3 ***
*** fprint 4 ***
fopenのまとめ
modeに”w”を含む場合、ファイルが既に存在する場合は、ファイルの内容がクリアされる
modeに”a”を含む場合、ファイルが既に存在する場合は、ファイルの最後に追加される
modeに”+”を含む場合、入力も出力の操作も可能
ただし、入力後に出力、出力後に入力を行う場合は、ファイル位置付け関数(fseek,fsetpos若しくはrewind)の呼び出しが必要
modeに”b”を含む場合、バイナリファイルのオープンになる