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