/* C/C++あれこれ/Excel仕様のCSVファイルの読み込みと表示 http://winter-tail.sakura.ne.jp/pukiwiki/index.php?C%A1%BFC%2B%2B%A4%A2%A4%EC%A4%B3%A4%EC%2FExcel%BB%C5%CD%CD%A4%CECSV%A5%D5%A5%A1%A5%A4%A5%EB%A4%CE%C6%C9%A4%DF%B9%FE%A4%DF%A4%C8%C9%BD%BC%A8 を、私が忘れないことを目的として張り付けさせて頂きました 原作者は台北猫々さん(http://winter-tail.sakura.ne.jp/index.shtml)です。 mingwでも問題なく動いており、心より感謝申し上げます。 */ /* ==================== okinawa.csv ========================= */ 47201,"900 ","9000,""000","オキナワケン","ナハシ","イカニケイサイガナイバアイ","沖縄県","那覇市","以下に掲載がない場合",0,0,0,0,0,0 47201,"90101","9010154","オキナワケン","ナハシ","アカミネ","沖縄県","那覇市","赤嶺",0,0,0,0,0,0 /* ==================== main.cpp ========================= */ /* g++ -g main.cpp CSVReader.cpp -o CSVReader でmingwでコンパイルできます */ #include <iostream> #include <string> #include <vector> #include <fstream> using namespace std; #include "CSVReader.h" int main(void) { std::fstream r("c:\\okinawa.csv", std::ios::in); if( !r.is_open() ) { cerr << "Open Error! :" << endl; return -1; } CSVReader csv(r); vector<string> tokens; while( !csv.Read(tokens) ) { for( unsigned int i=0; i<tokens.size(); i++ ) { //cout << "[" << tokens[i].c_str() << "]" << endl; // ここちょっっとテスト printf("[%s]\n",tokens[i].c_str()); } } csv.Close(); return 0; } /* ==================== CSVReader.h ========================= */ /** * CSVファイル読み込みクラス * @author 台北猫々 * @version CVS $Id: CSVReader.h,v 1.1 2008/03/26 12:45:24 tamamo Exp $ * @license BSD license: * Copyright (c) 2008, Taipei Cat Project * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the Taipei Cat Project nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _CSVREADER_H__ #define _CSVREADER_H__ #include <string> #include <vector> #include <fstream> using namespace std; #define DEFAULT_SEPARATOR ',' #define DEFAULT_QUOTE_CHARACTER '"' class CSVReader { public: /** * コンストラクタ * @param stream ファイルストリーム * @comment セパレータ(,), エンクオート(") */ CSVReader(fstream& stream); /** * コンストラクタ * @param stream ファイルストリーム * @param sep セパレータ * @comment エンクオート(") */ CSVReader(fstream& stream, const char sep); /** * コンストラクタ * @param stream ファイルストリーム * @param sep セパレータ * @param quo エンクオート */ CSVReader(fstream& stream, const char sep, const char quo); /** * デストラクタ */ virtual ~CSVReader(void); /** * CSVファイルを1行読み込んで、分割して配列で返します。 * @param tokens トークン(OUT) * @return 0:正常 -1:EOF */ int Read(vector<string>& tokens); /** * ファイルストリームをクローズします。 * @return 0:正常 -1:異常 */ int Close(void); private: /** * ファイルから1行読み込みます。 * @param line 行データ * @return >=0:読み込んだデータ長 -1:EOF */ int GetNextLine(string& line); /** * データをパースします。 * @param nextLine 行データ * @param tokens パースしたデータの配列(OUT) * @return 0 */ int Parse(string& nextLine, vector<string>& tokens); std::fstream* pstream; char SEPARATOR; char QUOTE; }; #endif /* ==================== CSVReader.cpp ========================= */ /** * CSVファイル読み込みクラス * @author 台北猫々 * @version CVS $Id: CSVReader.cpp,v 1.1 2008/03/26 12:45:24 tamamo Exp $ * @license BSD license: * Copyright (c) 2008, Taipei Cat Project * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the Taipei Cat Project nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "CSVReader.h" CSVReader::CSVReader(fstream& stream): SEPARATOR(DEFAULT_SEPARATOR), QUOTE(DEFAULT_QUOTE_CHARACTER), pstream(&stream) { } CSVReader::CSVReader(fstream& stream, const char sep): SEPARATOR(sep), QUOTE(DEFAULT_QUOTE_CHARACTER), pstream(&stream) { } CSVReader::CSVReader(fstream& stream, const char sep, const char quo): SEPARATOR(sep), QUOTE(quo), pstream(&stream) { } CSVReader::~CSVReader(void) { } int CSVReader::Read(vector<string>& tokens) { tokens.clear(); string nextLine; if( GetNextLine(nextLine)<=0 ) { return -1; } Parse(nextLine, tokens); return 0; } int CSVReader::GetNextLine(string& line) { if( !pstream || pstream->eof() ) { return -1; } std::getline( *pstream, line ); return (int)line.length(); } int CSVReader::Parse(string& nextLine, vector<string>& tokens) { string token; bool interQuotes = false; do { if (interQuotes) { token += '\n'; if (GetNextLine(nextLine)<0) { break; } } for (int i = 0; i < (int)nextLine.length(); i++) { char c = nextLine.at(i); if (c == QUOTE) { if( interQuotes && (int)nextLine.length() > (i+1) && nextLine.at(i+1) == QUOTE ){ token += nextLine.at(i+1); i++; }else{ interQuotes = !interQuotes; if(i>2 && nextLine.at(i-1) != SEPARATOR && (int)nextLine.length()>(i+1) && nextLine.at(i+1) != SEPARATOR ){ token += c; } } } else if (c == SEPARATOR && !interQuotes) { tokens.push_back(token); token.clear(); } else { token += c; } } } while (interQuotes); tokens.push_back(token); return 0; } /** * ファイルストリームをクローズします。 * @return 0:正常 -1:異常 */ int CSVReader::Close(void) { if(pstream) { pstream->close(); pstream = NULL; } return 0; }