はじめに
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言語の学習に参考にしている書籍は、こちらです。非常にわかりやすく初心者の方におすすめの本です。
コメント