C/C++

【C言語】初心者向けにファイルの操作の方法を解説

C/C++

はじめに

C言語でファイルの操作の方法を初心者向けに解説します。ファイルには、以下2種類が存在します。

  • テキストファイル
  • バイナリファイル

ファイルの種類ごとに操作の方法を解説したいと思います。

ファイルの種類

テキストファイル

テキストファイルとは、文字として読めるデータを指します。拡張子としては、.txtなどが挙げられます。

バイナリファイル

テキストファイルとは、文字として読めないデータを指します。拡張子としては、.pngなどが挙げられます。pngは画像ファイルです。

ファイルの操作方法

テキストファイルの操作方法

コード1:fopen

fopen関数はファイルを開く基本的な関数です。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
	//  ファイルポインタ(出力用)
	FILE* file;
	//  ファイルを書き込み用にオープン(開く)
	file = fopen("c:¥¥test¥¥sample.txt", "w");
	if (file == NULL) {
		//  ファイルを開くことに失敗した場合エラーメッセージを出力する
		printf("ファイルが開けません。¥n");
		//  異常のため終了
		return 1;
	}
	//  ファイルにデータを書き込む
	fprintf(file, "Hello World.¥n");
	fprintf(file, "ABCDEF¥n");
	//  ファイルを閉じる
	fclose(file);
	return 0;
}

解説

このプログラムは、c:¥¥test¥¥sample.txt”を読み込み、Hello WorldとABCDEFという文字列を書き込むプログラムです。

ファイルの読み込み

fopen("c:¥¥test¥¥sample.txt", "w")でテキストファイルを開くことができます。これをfopen関数と呼びます。
fopen(ファイル名,モード)

モードの一覧は以下です。対象ファイルは機能によって使い分ける必要があります。

モードファイル機能ファイルが
存在しないとき
“r”テキスト読み取りエラー
“w”テキスト書き込み新規作成
“a”テキスト追加書き込み新規作成
“rb”バイナリ読み取りエラー
“wb”バイナリ書き込み新規作成
“ab”バイナリ追加書き込み新規作成
“r+”テキスト更新(読み取り及び書き込み)エラー
“w+”テキスト更新(読み取り及び書き込み)新規作成
“a+”テキスト更新(追加書き込み)新規作成
“r+b” もしくは
“rb+”
バイナリ更新(読み取り及び書き込み)エラー
“w+b” もしくは
“wb+”
バイナリ更新(読み取り及び書き込み)新規作成
“a+b” もしくは
“ab+”
バイナリ更新(追加書き込み)新規作成
ファイルの書き込み

読み込んだファイルへの書き込みは、fprintf関数を用います。
fprintf(ファイルポインタ,書き込み文字列,変数・・・)

ファイルを閉じる

ファイルを閉じるには、fclose関数を用います。書式は、fclose(ファイルポインタ)です。

コード2:fgets関数

fgets関数は、テキストデータから1行読み出すのに使用する関数です。

#include <stdio.h>
#include <stdlib.h>

#define SIZE    256

int main(int argc, char** argv) {
	//  ファイルポインタ(読み込み用)
	FILE* file;
	//  読み込む行
	char line[SIZE];
	//  初期化(空文字列)
	line[0] = '¥0';
	//  ファイルを開く
	file = fopen("c:¥¥test¥¥sample.txt", "r");
	if (file == NULL) {
		//  失敗した場合エラーメッセージを出して終了
		printf("ファイルが開けません。¥n");
		return 1;
	}
	//  ファイルのデータ読み込む
	while (fgets(line, SIZE, file) != NULL) {
		printf("%s", line);
	}
	//  ファイルを閉じる
	fclose(file);
	return 0;
}

解説

テキストデータから1行読み出す

fgets関数の書式は以下です。fgets(文字列,文字列サイズ,ファイルポインタ)
上記のコードでは、NULLが返ってくるまで、文字列を読み込むというというプログラムでwhile分で記述されています。

コード3:fgetc関数

fgetc関数は、テキストデータから1文字ずつ読み出すのに使用する関数です。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
	//  ファイルポインタ(読み込み用)
	FILE* file;
	//  読み込む文字のコード
	int c;
	//  ファイルを読み込み用に開く
	file = fopen("c:¥¥test¥¥sample.txt", "r");
	if (file == NULL) {
		//  オープンに失敗した場合異常終了
		printf("ファイルが開けません。¥n");
		return 1;
	}
	//  ファイルのデータ読み込む
	while ((c = fgetc(file)) != EOF) {
		printf("%c", (char)c);
	}
	//  ファイルを閉じる
	fclose(file);
	return 0;
}

解説

fgetc関数の書式は以下です。fgets(ファイルポインタ)となります。
表示には、文字の表示を表す%cを使います。また、char型でキャストして文字として表示しています。

EOFとはファイル終了を表すマクロです。数値としては、-1と同等です。
このプログラムでは、EOFが出るまで読み続けるという意味のプログラムになっています。

バイナリファイルの操作方法

コード1:バイナリファイルの読み込みと書き込み

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
	FILE* file;
	int i;
	//  書き込むデータ
	char wdata[] = { 0x10 , 0x1a , 0x1e , 0x1f };
	char rdata[4];
	//  バイナリデータの書き込み
	file = fopen("C:¥¥test¥¥test.bin", "wb");
	if (file == NULL) {
		printf("ファイルオープンに失敗しました。¥n");
		return 1;
	}
	fwrite(wdata, sizeof(char), sizeof(wdata), file);
	fclose(file);          //  ファイルを閉じる
	//  バイナリデータの読み込み
	file = fopen("C:¥¥test¥¥test.bin", "rb");
	if (file == NULL) {
		printf("ファイルオープンに失敗しました。¥n");
		return 1;
	}
	fread(rdata, sizeof(char), sizeof(rdata), file);
	fclose(file);          //  ファイルを閉じる
	//  結果を表示
	for (i = 0; i < sizeof(rdata); i++) {
		printf("%x ", rdata[i]);
	}
	printf("¥n");
	return 0;
}

解説

fileにchar wdataを書き込むプログラムです。C:¥¥test¥¥test.binに格納されているbinファイルを弓出しています。これは、C直下のtestフォルダに格納されているという意味です。

fwrite関数

fwrite関数とは、バイナリファイルの書き込みに使用します。fwrite関数の書式は、以下です。

fwrite(データ,ファイル要素一つあたりの大きさ,要素の数,ファイルポインタ)

この例では、char型の配列wdataのデータを書き込んでいます。

fwrite(wdata, sizeof(char), sizeof(wdata), file);

fread関数

fread関数とは、バイナリファイルの読み込みに使用します。fread関数の書式は、以下です。

fread(データ,ファイル要素一つあたりの大きさ,要素の数,ファイルポインタ)

この例では、char型の配列rdataのデータを書き込んでいます。

fread(rdata, sizeof(char), sizeof(rdata), file);

サイズがわからないバイナリファイルの読み込み

読み込みたいバイナリファイルのサイズが不明なケースでは以下のコードを使用します。

コード1:fseek関数、ftell関数

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
	FILE* file;
	int i, size;
	//  読み込むデータ
	char* rdata;
	//バイナリデータの読み込み
	file = fopen("C:¥¥test¥¥test.bin", "rb");
	if (file == NULL) {
		printf("ファイルオープンに失敗しました。¥n");
		return 0;
	}
	//  ファイルの最後までシーク
	fseek(file, 0, SEEK_END);
	//  ファイルの大きさを取得
	size = ftell(file);
	//  メモリのサイズだけ、配列を動的に生成
	rdata = (char*)malloc(sizeof(char) * size);
	//  ファイルの最初にポインタを戻す
	fseek(file, 0, SEEK_SET);
	fread(rdata, sizeof(char), size, file);
	//  ファイルを閉じる
	fclose(file);
	//  結果を表示
	for (i = 0; i < size; i++) {
		printf("%x ", rdata[i]);
	}
	printf("¥n");
	//  メモリ解放
	free(rdata);
	return 0;
}

解説

fseek関数とftell関数を使うことで、ファイルのサイズを取得することができます。それぞれの書式は、以下です。この関数は、テキストファイル、バイナリーファイルのどちらにも使用可能です。

fseek(ファイルポインタ,移動バイト数,開始位置)

ftell(ファイルポインタ)

fseek関数で使われる開始位置
  • SEEK_SET:ファイルの先頭
  • SEEK_CUR:ファイルの現在位置
  • SEEK_END:ファイルの終端

まとめ

ファイルの種類ごとにC言語での操作の方法を解説しました。
C言語で読み出すファイルは、以下2種類です。

  • テキストファイル
    • fopen:ファイルを開く
    • fgets:1行の文字列を取得
    • fgetc:一文字を取得
    • fprintf:ファイル書き込み
  • バイナリファイル
    • fopen:ファイルを開く
    • fwrite:ファイル書き込み
    • fread:ファイル読み込み

fseek関数とftell関数を使うことで、ファイルのサイズを取得することができます。この関数は、テキストファイル、バイナリーファイルのどちらにも使用可能です。

C言語の学習に参考にしている書籍は、こちらです。非常にわかりやすく初心者の方におすすめの本です。

コメント

タイトルとURLをコピーしました