ファイルに対してデータを読み込み、書き込みするときに使える関数を紹介します。
fread:ファイルからデータを読み取る関数
size_t fread(void *buf,size_t size,size_t n,FILE *fp);
fpが指すファイルからsizeバイトのデータをn個読み取り、bufが指す配列に格納する。操作が成功するとnを返し、失敗またはファイルの末端に達した場合は実際に読み取れたデータの数(n未満)を返す。
fwrite:ファイルにデータを書き込む関数
size_t fread(const void *buf,size_t size,size_t n,FILE *fp);
fpが指すファイルにbufが指すsizeバイトのデータをn個書き込む。操作が成功するとnを返し、失敗またはファイルの末端に達した場合は実際に書き込めたデータの数(n未満)を返す。
この2つの関数を用いて、ファイルをコピーするプログラムを作成します。データをまとめて機械的に扱うので、バイナリファイルとしてファイルを開きます。
#include <stdio.h>
#include <stdlib.h>
int main(void){
char rname[500],wname[500];
unsigned char data;
int i;
FILE *rfp,*wfp;
puts("コピー元ファイルのパス:");
scanf("%s",rname);
puts("コピー先ファイルのパス:");
scanf("%s",wname);
if ((rfp=fopen(rname,"rb"))==NULL){
puts("ファイルを開けません。");
return -1;
}
if ((wfp=fopen(wname,"wb"))==NULL){
puts("ファイルを開けません。");
fclose(rfp);
return -1;
}
while (1){
if (fread(&data, sizeof(data),1,rfp)<1) break;
if (fwrite(&data, sizeof(data),1,wfp)<1) break;
}
fclose(rfp);
fclose(wfp);
return 0;
}
このサンプルコードでは、1バイトずつデータを読み取り、書き込んでいきます。エラーが発生すると、fread関数またはfwrite関数は1より小さい数を返すので、そのときは無限ループから抜け出します。
次に、ファイルの中身をダンプするプログラムを説明します。コンソール画面の左側に16進数で表示し、右側に文字を表示します。改行コードなどの特殊文字は表記できないので.で表します。
表示できる文字かどうかを判断するにはisprint関数を用います。
int isprint(int c);
cが表示可能な文字であれば、0以外を返します。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define LINE 10
int main(void){
char rname[500];
unsigned char data[LINE];
int i;
FILE *fp;
puts("コピー元ファイルのパス:");
scanf("%s",rname);
if ((fp=fopen(rname,"rb"))==NULL){
puts("ファイルを開けません。");
return -1;
}
while (1){
if (fread(data, sizeof(unsigned char),LINE,fp)<LINE) break;
for (i=0;i<LINE;i++){
printf("%02X ",data[i]);
}
for (i=0;i<LINE;i++){
if (isprint(data[i])) printf("%c",data[i]);
else printf(".");
}
puts("");
}
fclose(fp);
return 0;
}
まとめ
fread関数、fwrite関数を用いるとまとまった量のデータを一気に読み書きできる。
コメント