10-5 ファイルのコピーとダンプ

この記事は約4分で読めます。

ファイルに対してデータを読み込み、書き込みするときに使える関数を紹介します。

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関数を用いるとまとまった量のデータを一気に読み書きできる。

コメント