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を使った方がいいのかもしれない.