C++らしいファイル読み込みをしたい

C言語のファイル読み込みといえばfopenだが,必ずfcloseしなければならないなど面倒くさい.

そこでC++のifstreamを使ってみる.

テキストデータを読み込み,整数として処理するプログラムをサンプルとして作成した.

比較のためifstreamとfopenの両方の処理を載せた.

ifstreamではsscanf
fopenではfscanf

をそれぞれ利用する.

sscanfはstd::string型から
fscanfはFILE*型から
指定書式に従ってデータを読み込むことができる.

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int main() {

	//ifstreamの場合
	cout << "ifstream" << endl;

	ifstream ifs("data.txt");
	string str;

	if(ifs.fail()) {
		cerr << "File do not exist.\n";
		exit(0);
	}

	int a=0, b=0, c=0;

	while(getline(ifs, str)) {
		a=0; b=0; c=0;
		sscanf(str.data(), "%d,%d,%d", &a, &b, &c);

		cout << "a = " << a << endl;
		cout << "b = " << b << endl;
		cout << "c = " << c << endl;
		cout << "a+b+c = " << a+b+c << endl;
	}

	//fopenの場合
	cout << endl << "fopen" << endl;
	a=0; b=0; c=0;

	FILE* fp;
	if((fp = fopen("data.txt", "r")) == NULL) {
		printf("File do not exist.\n");
		exit(0);
	}

	while(fscanf(fp, "%d,%d,%d", &a, &b, &c) != EOF) {
		printf("a = %d\n", a);
		printf("b = %d\n", b);
		printf("c = %d\n", c);
		printf("a+b+c = %d\n", a+b+c);
		a=0; b=0; c=0;
	}

	fclose(fp);

	return 0;
}

data.txt

10,100,-6
50,10000,2
-90,20
-90,-53,92

結果

ifstream
a = 10
b = 100
c = -6
a+b+c = 104
a = 50
b = 10000
c = 2
a+b+c = 10052
a = -90
b = 20
c = 0
a+b+c = -70
a = -90
b = -53
c = 92
a+b+c = -51

fopen
a = 10
b = 100
c = -6
a+b+c = 104
a = 50
b = 10000
c = 2
a+b+c = 10052
a = -90
b = 20
c = 0
a+b+c = -70
a = -90
b = -53
c = 92
a+b+c = -51


実装の手間はほとんど変わらないので,どっちを使うかは完全に好みだろう.


以下のように処理を簡略し,ifstream&sscanfとfopen&fscanfで処理速度を比較してみた.

ifstream&sscanf

clock_t t1, t2;
	
	t1 = clock();
	
	for(int i=0; i<10000000; i++) {
		while(getline(ifs, str)) {
			sscanf(str.data(), "%d,%d,%d", &a, &b, &c);
		}
	}

	t2 = clock();

	cout << (double)(t2 - t1)/CLOCKS_PER_SEC << endl;

fopen&fscanf

	t1 = clock();

	for(int i=0; i<10000000; i++) {
		while(fscanf(fp, "%d,%d,%d", &a, &b, &c) != EOF) {
		}
	}
	t2 = clock();

	cout << (double)(t2 - t1)/CLOCKS_PER_SEC << endl;

結果

ifstream
5.649

fopen
14.64


ifstreamの方が遅いと思っていたが,予想に反して倍以上ifstreamの方が速かった.


この結果が正しいかわからないが,処理速度の面で見るとifstreamを使った方がいいのかもしれない.