CSVファイルアクセスクラス
良さげなものがWEBで見つからなかったので、自分で無理矢理作ってみる。
※ 2013年11月25日
以下の記事もご覧になった方が良いかもしれません。
TStrings::CommaTextは半角スペースも区切り文字とみなす - 涼の成長記録
TCsvFileAccess.h
/*! @file TCsvFileAccess.h @brief CSVファイルアクセスクラスの宣言 */ #ifndef TCsvFileAccessH #define TCsvFileAccessH #include <vector> namespace Common { namespace FileAccess { //! [縦][横]の2次元配列。 typedef std::vector<std::vector<UnicodeString> > CSV_VECTOR; // ↑スペースが無いとシフト演算子に優先度負ける。 /*! CSVファイルアクセスクラス CSVファイルアクセスを行うクラスのベースとしてヘルパーを担う。 コンストラクターでファイルのパスを渡して、 read(), write()メソッドで、指定のフィールドへアクセスする。 @note TStringListはVCL特有のクラスであるため、VC++等に対しての移植性は無い。 将来的には、fstream等を使って実装してみたい。。 */ class TCsvFileAccess { public: /*! コンストラクター @param filePath :CSVファイルのパス */ __fastcall TCsvFileAccess(const UnicodeString &filePath); /*! 仮想デストラクター */ virtual __fastcall ~TCsvFileAccess(); /** コンストラクターで渡されたファイルパスが存在すればtrueを返す。 @return ファイルがあればtrue。なければfalse。 */ bool __fastcall isFileExist(); /*! 読み込み。 ファイルが無ければ、デフォルト値を書込む。 @param array :読込んだデータを格納する2次元配列の参照。 そのサイズから、読込む行数と列数を取得するので、 取得しておきたい行数と列数分のサイズを確保しておくこと。 @@return 正常時true。行数、列数が足りなかった場合等はfalse。 */ bool __fastcall read(CSV_VECTOR &array); /*! 書き込み。 2次元配列のarrayをコンマ区切りでCSVファイルへ出力する。 @param array :書込む2次元配列の参照 @return なし。 */ void __fastcall write(const CSV_VECTOR &array); private: //! ファイル名称 const UnicodeString m_FilePath; }; } // namespace FileAccess } // namespace Common #endif
TCsvFileAccess.cpp
/*! @file TCsvFileAccess.cpp @brief CSVファイルアクセスクラスの実装 */ #include <vcl.h> #pragma hdrstop #include <IOUtils.hpp> #include <vector> #include "TCsvFileAccess.h" #pragma package(smart_init) namespace Common { namespace FileAccess { //------------------------------------------------------------------------------ // コンストラクター //------------------------------------------------------------------------------ __fastcall TCsvFileAccess::TCsvFileAccess(const UnicodeString &filePath) : m_FilePath(filePath) { // フォルダーを作成しておく。 try { ForceDirectories(TPath::GetDirectoryName(m_FilePath)); } catch (...) { // 例外もぐもぐ。。 } } //------------------------------------------------------------------------------ // ファイルがあればtrueを返す //------------------------------------------------------------------------------ bool __fastcall TCsvFileAccess::isFileExist() { return FileExists(m_FilePath); } //------------------------------------------------------------------------------ // 読み込み。 //------------------------------------------------------------------------------ bool __fastcall TCsvFileAccess::read(CSV_VECTOR &array) { // 読込むファイルが無ければ異常 if (!FileExists(m_FilePath)) { return false; } TStringList *line = new TStringList; // 一行分のデータ。 TStringList *file = new TStringList; // ファイル全体分のデータ。 try { // 項目数エラーや、異常値等で簡単に例外が発生する。 file->LoadFromFile(m_FilePath); for (unsigned int i = 0; i < array.size(); i++) { line->CommaText = file->Strings[i]; for (unsigned int j = 0; j < array.at(i).size(); j++) { array.at(i).at(j) = line->Strings[j]; } } } catch (...) { delete line; delete file; return false; } delete line; delete file; return true; } //------------------------------------------------------------------------------ // 書き込み。 //------------------------------------------------------------------------------ void __fastcall TCsvFileAccess::write(const CSV_VECTOR &array) { TStringList *line = new TStringList; // 一行分のデータ。 TStringList *file = new TStringList; // ファイル全体分のデータ。 file->Clear(); for (unsigned int row = 0; row < array.size(); row++) { line->Clear(); for (unsigned int col = 0; col < array.at(row).size(); col++) { line->Add(array.at(row).at(col)); } file->Add(line->CommaText); } file->SaveToFile(m_FilePath); delete line; delete file; } } // namespace FileAccess } // namespace Common