3
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

updated at

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

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

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

参考ページ

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
3
Help us understand the problem. What are the problem?