LoginSignup
5
3

More than 3 years have passed since last update.

C++でglobして、ついでにその中にあるテキストファイルを読み込む

Last updated at Posted at 2019-06-10

初投稿です。
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

出力は、テキストファイル内の数字の和を返しています。

参考ページ

5
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3