fread関数:C言語でバイナリファイルを読み書きするためのチュートリアル
fread 関数は、C言語においてバイナリファイルからデータを効率的に読み込むために使用されます。バイナリファイルは、テキストファイルとは異なり、数値データをそのまま保存するファイル形式です。fread 関数は、ファイルポインタ、読み込むデータの要素サイズ、読み込む要素数、読み込むファイルポインタを引数として受け取り、読み込まれた要素数を返します。
fread 関数の詳細
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
stream
: 読み込み対象のファイルポインタcount
: 読み込む要素数size
: 読み込むデータの要素サイズ (バイト単位)ptr
: 読み込まれたデータが格納されるポインタ
fread 関数の動作
- fread 関数は、
stream
で指定されたファイルからsize
バイトのデータをptr
で指されるメモリ領域に読み込みます。 - 読み込まれたデータの要素数は
count
で指定されます。 - fread 関数は、正常に読み込まれた要素数を返します。
- ファイル末に到達した場合、またはエラーが発生した場合は、 fread 関数は
0
以下の値を返します。
fread 関数の利点
- ファイルの読み込み位置を制御することができます。
- 様々なデータ型を扱うことができます。
- バイナリファイルから効率的にデータを読み込むことができます。
fread 関数の例
#include <stdio.h>
int main() {
int data[10];
FILE *fp;
// ファイルを開く
fp = fopen("data.bin", "rb");
if (fp == NULL) {
printf("ファイルを開けません\n");
return 1;
}
// ファイルからデータを読み込む
size_t read_count = fread(data, sizeof(int), 10, fp);
if (read_count < 10) {
printf("データを読み込めません\n");
fclose(fp);
return 1;
}
// 読み込んだデータを処理する
for (int i = 0; i < 10; i++) {
printf("%d ", data[i]);
}
// ファイルを閉じる
fclose(fp);
return 0;
}
この例では、"data.bin" というバイナリファイルから 10 個の整数を読み込み、コンソールに出力します。
- エラー処理を適切に行う必要があります。
- ファイルの読み込み位置を制御するには、
fseek
関数と組み合わせて使用する必要があります。 - fread 関数はバイナリファイルでのみ使用できます。
整数データの読み込み
#include <stdio.h>
int main() {
int data[10];
FILE *fp;
// ファイルを開く
fp = fopen("data.bin", "rb");
if (fp == NULL) {
printf("ファイルを開けません\n");
return 1;
}
// ファイルからデータを読み込む
size_t read_count = fread(data, sizeof(int), 10, fp);
if (read_count < 10) {
printf("データを読み込めません\n");
fclose(fp);
return 1;
}
// 読み込んだデータを処理する
for (int i = 0; i < 10; i++) {
printf("%d ", data[i]);
}
// ファイルを閉じる
fclose(fp);
return 0;
}
構造体データの読み込み
このコードは、"data.bin" というバイナリファイルから student
構造体のデータを読み込み、コンソールに出力します。
#include <stdio.h>
typedef struct {
int id;
char name[20];
double score;
} student_t;
int main() {
student_t student;
FILE *fp;
// ファイルを開く
fp = fopen("data.bin", "rb");
if (fp == NULL) {
printf("ファイルを開けません\n");
return 1;
}
// ファイルからデータを読み込む
size_t read_count = fread(&student, sizeof(student_t), 1, fp);
if (read_count < 1) {
printf("データを読み込めません\n");
fclose(fp);
return 1;
}
// 読み込んだデータを処理する
printf("ID: %d\n", student.id);
printf("名前: %s\n", student.name);
printf("点数: %lf\n", student.score);
// ファイルを閉じる
fclose(fp);
return 0;
}
文字列データの読み込み
このコードは、"data.bin" というバイナリファイルから NULL 文字で区切られた文字列を読み込み、コンソールに出力します。
#include <stdio.h>
int main() {
char str[100];
FILE *fp;
// ファイルを開く
fp = fopen("data.bin", "rb");
if (fp == NULL) {
printf("ファイルを開けません\n");
return 1;
}
// ファイルからデータを読み込む
size_t read_count = fread(str, sizeof(char), sizeof(str) - 1, fp);
if (read_count < 0) {
printf("データを読み込めません\n");
fclose(fp);
return 1;
}
// 読み込んだデータを処理する
str[read_count] = '\0'; // NULL 文字を追加
printf("%s\n", str);
// ファイルを閉じる
fclose(fp);
return 0;
}
ファイル全体を読み込む
このコードは、"data.bin" というバイナリファイルのすべての内容を読み込み、コンソールに出力します。
#include <stdio.h>
int main() {
FILE *fp;
long file_size;
char *buffer;
// ファイルを開く
fp = fopen("data.bin", "rb");
if (fp == NULL) {
printf("ファイルを開けません\n");
return 1;
}
// ファイルサイズを取得
fseek(fp, 0, SEEK_END);
file_size = ftell(fp);
fseek(fp, 0, SEEK_SET);
// ファイル内容を読み込むためのバッファを確保
buffer = malloc(file_size + 1);
if (buffer == NULL) {
printf("メモリを確保できません\n");
fgetc 関数と fputc 関数
fgetc 関数は、ファイルから 1 文字ずつ読み込み、その文字を返します。fputc 関数は、ファイルに 1 文字ずつ書き込みます。これらの関数は、小さなデータや 1 文字ずつ処理する必要がある場合に適しています。
#include <stdio.h>
int main() {
FILE *fp;
char ch;
// ファイルを開く
fp = fopen("data.txt", "r");
if (fp == NULL) {
printf("ファイルを開けません\n");
return 1;
}
// ファイルから文字を読み込む
while ((ch = fgetc(fp)) != EOF) {
printf("%c", ch);
}
// ファイルを閉じる
fclose(fp);
return 0;
}
fscanf 関数と fprintf 関数
fscanf 関数は、ファイルから書式化されたデータを読み込みます。fprintf 関数は、ファイルに書式化されたデータを書き込みます。これらの関数は、フォーマットされたデータの読み書きに適しています。
#include <stdio.h>
int main() {
FILE *fp;
int num;
char name[20];
// ファイルを開く
fp = fopen("data.txt", "r");
if (fp == NULL) {
printf("ファイルを開けません\n");
return 1;
}
// ファイルからデータを読み込む
fscanf(fp, "%d %s", &num, name);
printf("数値: %d, 名前: %s\n", num, name);
// ファイルを閉じる
fclose(fp);
return 0;
}
fgets 関数と fputs 関数
fgets 関数は、ファイルから 1 行の文字列を読み込み、その文字列を返します。fputs 関数は、ファイルに 1 行の文字列を書き込みます。これらの関数は、テキストファイルの読み書きに適しています。
#include <stdio.h>
int main() {
FILE *fp;
char line[100];
// ファイルを開く
fp = fopen("data.txt", "r");
if (fp == NULL) {
printf("ファイルを開けません\n");
return 1;
}
// ファイルから行を読み込む
while (fgets(line, sizeof(line), fp) != NULL) {
printf("%s", line);
}
// ファイルを閉じる
fclose(fp);
return 0;
}
カスタム関数
特定のニーズに合致する代替手段がない場合は、カスタム関数を作成することができます。カスタム関数は、fread 関数よりも柔軟性と制御性に優れていますが、開発とテストにはより多くの時間と労力が必要です。
- コードの簡潔性
- パフォーマンス要件
- データの処理方法
- 読み込むデータの種類と量