C++ - CSV データ読み込み!
Updated:
CSV データファイルを読み込む C++ コードです。
0. 前提条件
- LMDE2 (Linux Mint Debian Edition 2) での作業を想定。
- g++ 4.9.2 でのコンパイルを想定。
- 当方、 C++ に長けていないので、綺麗なコーディングではないかもしれない。
1. C++ コードの作成
簡単なソースコードなので1ファイルで作成してもよかったが、今後部品として再利用することも考慮してヘッダ・ソース・実行ファイルに分割している。
【ヘッダファイル】
File: csv.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
* @file csv.hpp
* @brief CSV 読み込み処理
*
* @date 2017-01-10 新規作成
* @author mk-mode.com
*/
#ifndef INCLUDED_CSV_HPP
#define INCLUDED_CSV_HPP
#include <string>
#include <vector>
/**
* @class Csv
* @brief CSV 処理クラス
*/
class Csv
{
//! CSV ファイル名
std::string csv_file;
public:
//! コンストラクタ
Csv(std::string);
//! CSV データ取得
bool getCsv(std::vector<std::vector<std::string>>&, const char delim = ',');
};
#endif
【ソースファイル】
File: csv.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
* @file csv.cpp
* @brief CSV 処理クラス
*
* @date 2017-01-10 新規作成
* @author mk-mode.com
*/
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include "csv.hpp"
using namespace std;
/**
* @brief コンストラクタ
*
* @param[in] CSVファイル(string)
* @return 真偽(bool)
* @retval true 成功
* @retval false 失敗
*/
Csv::Csv(string csv_file)
{
this->csv_file = csv_file;
}
/**
* @brief CSV データ取得
*
* @param[in] CSV ファイル名(string&)
* @param[out] CSV データ(vector<vector<string>>&)
* @param[in] デリミッタ(const char)
* @return 真偽(bool)
* @retval true 成功
* @retval false 失敗
*/
bool Csv::getCsv(vector<vector<string>>& data, const char delim)
{
// ファイルOPEN
ifstream ifs(csv_file);
if (!ifs.is_open()) return false; // 読み込み失敗
// ファイルREAD
string buf; // 1行分バッファ
while (getline(ifs, buf)) {
vector<string> rec; // 1行分ベクタ
istringstream iss(buf); // 文字列ストリーム
string field; // 1列分文字列
// 1列分文字列を1行分ベクタに追加
while (getline(iss, field, delim)) rec.push_back(field);
// 1行分ベクタを data ベクタに追加
if (rec.size() != 0) data.push_back(rec);
}
return true; // 読み込み成功
}
【実行ファイル】
File: read_csv.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
* @file read_csv.cpp
* @brief CSVファイル読込み
*
* @date 2017-01-10 新規作成
* @author mk-mode.com
*/
#include <iostream>
#include <string>
#include <vector>
#include "csv.hpp"
using namespace std;
/**
* @brief メイン処理
*
* @param[in] <none>
* @param[out] <none>
* @return リターンコード(int)
* @retval 0 正常終了
* @retval 1 異常終了
*/
int main()
{
const string csv_file = "sample.csv"; //! CSVファイル
vector<vector<string>> data; //! CSVデータ
try {
// CSVデータ取得
Csv objCsv(csv_file);
if (!objCsv.getCsv(data)) {
cout << "[ERROR] 読込み失敗!" << endl;
return 1;
}
// 内容出力
for (unsigned int row = 0; row < data.size(); row++) {
vector<string> rec = data[row]; // 1行
for (unsigned int col = 0; col < rec.size(); col++) {
cout << rec[col]; // 1列
if (col < rec.size() - 1) cout << ","; // 行末以外はカンマ出力
}
cout << endl;
}
}
catch (...) {
cout << "EXCEPTION!" << endl;
return 1;
}
return 0;
}
2. コンパイル
$ g++ -Wall -O2 read_csv.cpp csv.cpp -o read_csv -std=c++11
もしくは、
$ g++ -Wall -O2 -c csv.cpp -o csv.o -std=c++11
$ g++ -Wall -O2 -c read_csv.cpp -o read_csv.o -std=c++11
$ g++ -Wall -O2 read_csv.o csv.o -o read_csv
-std=c++11
は、テンプレートの右シフト問題対策。
(vector<vector<string>>
の>>
が右シフトと認識されないため)
c++0x
でもよいが、c++03
はNG.
3. CSV データサンプル
テスト用に CSV データファイルを作成する。(ファイル名: “sample.csv”)
File: sample.csv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
20110106,-0.2
20110512,-0.3
20111104,-0.4
20120209,-0.5
20120510,-0.6
20120701, 0.4
20121025, 0.3
20130131, 0.2
20130411, 0.1
20130822, 0.0
20131121,-0.1
20140220,-0.2
20140508,-0.3
20140925,-0.4
20141225,-0.5
20150319,-0.6
20150528,-0.7
20150701, 0.3
20150917, 0.2
20151126, 0.1
20160131, 0.0
20160324,-0.1
20160519,-0.2
20160901,-0.3
4. 実行
$ ./read_csv
20110106,-0.2
20110512,-0.3
20111104,-0.4
20120209,-0.5
20120510,-0.6
20120701, 0.4
20121025, 0.3
20130131, 0.2
20130411, 0.1
20130822, 0.0
20131121,-0.1
20140220,-0.2
20140508,-0.3
20140925,-0.4
20141225,-0.5
20150319,-0.6
20150528,-0.7
20150701, 0.3
20150917, 0.2
20151126, 0.1
20160131, 0.0
20160324,-0.1
20160519,-0.2
20160901,-0.3
あちこちで利用できるでしょう。
以上。
Comments