Created
March 7, 2020 04:50
-
-
Save komasaru/ae27e6ff2b86f9bef6e06b355b5766bc to your computer and use it in GitHub Desktop.
C++ source code to read csv data(v2).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "csv.hpp" | |
#include <iostream> | |
#include <string> | |
#include <vector> | |
// getline: 1行取得し、必要に応じて伸張 | |
int Csv::getline(std::string& str) { | |
char c; | |
for (line = ""; fin.get(c) && !endofline(c); ) | |
line += c; | |
split(); | |
str = line; | |
return !fin.eof(); | |
} | |
// endofline: \r, \n, \r\n, EOF をチェックして捨てる | |
int Csv::endofline(char c) { | |
int eol; | |
eol = (c == '\n' || c == '\n'); | |
if (c == '\r') { | |
fin.get(c); | |
if (!fin.eof() && c != '\n') | |
fin.putback(c); // 読みすぎ | |
} | |
return eol; | |
} | |
// split: 行をフィールド単位に分割 | |
int Csv::split() { | |
std::string fld; | |
unsigned int i, j; | |
nfield = 0; | |
if (line.length() == 0) | |
return 0; | |
i = 0; | |
do { | |
if (i < line.length() && line[i] == '"') | |
j = advquoted(line, fld, ++i); // クォートをスキップ | |
else | |
j = advplain(line, fld, i); | |
if (nfield >= field.size()) | |
field.push_back(fld); | |
else | |
field[nfield] = fld; | |
nfield++; | |
i = j + 1; | |
} while (j < line.length()); | |
return nfield; | |
} | |
// advquoted: クォートでくくられたフィールド: 次のセパレータのインデックスを返す | |
int Csv::advquoted(const std::string& s, std::string& fld, int i) { | |
unsigned int j; | |
fld = ""; | |
for (j = i; j < s.length(); j++) { | |
if (s[j] == '"' && s[++j] != '"') { | |
unsigned int k = s.find_first_of(fieldsep, j); | |
if (k > s.length()) // セパレータが見つからなかった | |
k = s.length(); | |
for (k -= j; k-- > 0; ) | |
fld += s[j++]; | |
break; | |
} | |
fld += s[j]; | |
} | |
return j; | |
} | |
// advplain: クォートでくくられていないフィールド: 次のセパレータのインデックスを返す | |
int Csv::advplain(const std::string& s, std::string& fld, int i) { | |
unsigned int j; | |
j = s.find_first_of(fieldsep, i); // セパレータを探す | |
if (j > s.length()) // 見つからなかった | |
j = s.length(); | |
fld = std::string(s, i, j - i); | |
return j; | |
} | |
// getfield: n番目のフィールドを返す | |
std::string Csv::getfield(unsigned int n) { | |
if (n < 0 || n >= nfield) | |
return ""; | |
else | |
return field[n]; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef TEST_CSV_CSV_HPP_ | |
#define TEST_CSV_CSV_HPP_ | |
#include <iostream> | |
#include <string> | |
#include <vector> | |
// CSV クラス | |
class Csv { // カンマで区切られた値を読んで解析する | |
std::istream& fin; // 入力ファイルポインタ | |
std::string line; // 入力行 | |
std::vector<std::string> field; // フィールド文字列 | |
unsigned int nfield; // フィールド数 | |
std::string fieldsep; // セパレータ文字 | |
int split(); | |
int endofline(char); | |
int advplain(const std::string& line, std::string& fld, int); | |
int advquoted(const std::string& line, std::string& fld, int); | |
public: | |
Csv(std::istream& fin = std::cin, std::string sep = ",") : | |
fin(fin), fieldsep(sep) {} | |
int getline(std::string&); | |
std::string getfield(unsigned int n); | |
int getnfield() const { return nfield; } | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/********************************************* | |
* CSV 読み込みテスト * | |
*********************************************/ | |
#include "csv.hpp" | |
#include <iostream> | |
#include <string> | |
#include <vector> | |
// TestCsv main: Csv クラスのテスト | |
int main(void) { | |
std::string line; | |
Csv csv; | |
while (csv.getline(line) != 0) { | |
std::cout << "line = '" << line << "'\n"; | |
for (int i = 0; i < csv.getnfield(); i++) | |
std::cout << "field[" << i << "] = '" | |
<< csv.getfield(i) << "'\n"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment