初投稿です。
C++でPythonの glob.glob()
みたいなことがしたいなーと思って軽く困ったので、tipsとして残しておきます。また、その中にあるテキストファイルの読み込みも少し詰まったのでそれに関してもついでに載せときます。
C++のglobでディレクトリ内のファイルを取得
まず、ディレクトリ構造は以下の通りです。
$ tree
.
├── input
│ ├── sample01.txt
│ ├── sample02.txt
│ ├── sample03.txt
│ └── sample04.txt
└── main.cpp
input
ディレクトリ下のテキストファイル4つを glob
を用いてワイルドカードで取得します。
main.cpp
#include <iostream>
#include <string>
#include <vector>
#include <glob.h>
using namespace std;
vector<string> get_file_path(string input_dir) {
glob_t globbuf;
vector<string> files;
glob((input_dir + "*.txt").c_str(), 0, NULL, &globbuf);
for (int i = 0; i < globbuf.gl_pathc; i++) {
files.push_back(globbuf.gl_pathv[i]);
}
globfree(&globbuf);
return files;
}
int main(int argc, char* argv[]) {
string input_dir = argv[1];
vector<string> files = get_file_path(input_dir);
string f;
for (const auto& f : files) {
cout << f << endl;
}
return 0;
}
出力
$ g++ -o main main.cpp
$ ./main ./input/
./input/sample01.txt
./input/sample02.txt
./input/sample03.txt
./input/sample04.txt
正常に取得できました。
テキストファイルを読み込む
次に、 fstream
を用いてテキストファイルを読み込んで行きます。
まず、テキストファイルの内容はそれぞれ以下のようになっています。
sample01.txt
5
sample02.txt
3.6
sample03.txt
9 19 75 2
sample04.txt
100 23 9.2
0.1
コードは以下の通りです。先ほどのコードに read_text
関数を加えました。
main.cpp
#include <iostream>
#include <string>
#include <vector>
#include <glob.h>
#include <fstream>
#include <cmath>
using namespace std;
vector<string> get_file_path(string input_dir) {
glob_t globbuf;
vector<string> files;
glob((input_dir + "*.txt").c_str(), 0, NULL, &globbuf);
for (int i = 0; i < globbuf.gl_pathc; i++) {
files.push_back(globbuf.gl_pathv[i]);
}
globfree(&globbuf);
return files;
}
double read_text(string f) {
ifstream ifs(f);
string l;
double sum_val = 0;
int first, last, count = 0;
while (getline(ifs, l)) {
count = 0;
first = 0;
last = l.find_first_of(" ");
while (first < l.size()) {
string subStr(l, first, last - first);
sum_val += atof(subStr.c_str());
first = last + 1;
last = l.find_first_of(" ", first);
if (last == string::npos) {
if (count == 0) break;
else last = l.size();
};
count++;
}
}
return sum_val;
}
int main(int argc, char* argv[]) {
string input_dir = argv[1];
vector<string> files = get_file_path(input_dir);
string f;
for (const auto& f : files) {
cout << f << endl;
cout << "sum = " << read_text(f) << endl;
}
return 0;
}
出力
$ ./main ./input/
./input/sample01.txt
sum = 5
./input/sample02.txt
sum = 3.6
./input/sample03.txt
sum = 105
./input/sample04.txt
sum = 132.3
出力は、テキストファイル内の数字の和を返しています。