Shoeisha Technology Media

CodeZine(コードジン)

記事種別から探す

StateパターンでCSVを読む

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2010/12/14 14:00

昼メシを賭けて同僚から頼まれたCSVファイルの処理プログラム。見通しよくデザインするために、Stateパターンを使ったC++での実装例を紹介します。

目次

 先日ちょっとした"やっつけ仕事"を頼まれました。Excelで作られたテーブル、例えば:

図1 Excel上のテーブル
図1 Excel上のテーブル

 こんなのを読み込んで適当な処理を施して欲しい、と。Excelのシートから各セルの値を拾い出すのはさほどに難しくはないのですが、いかんせん時間がなかったのでいったんはお断りしたところ、「Excelシートを直接読むのが面倒ならCSVからでもかまわん」とのこと。CSVならフツーにテキストファイルを読めばいいから小一時間で作れそう、昼メシ奢ってもらうのを報酬に引き受けることにしました。

CSVのフォーマット

 CSV(Comma Separated Values)はMS-DOSあるいはその以前からスプレッドシートのデータ・フォーマットとして使われています。CSVの規格/標準としてはRFC4180がありますが、こいつは2005年に作られたものでそれ以前のアプリケーションがRFC4180に準拠していることは期待できるはずもありません。とはいえ、まずはRFC4180に従って作られたCSVなら正しく読めることを目標とします。

 RFC4180によりますと:

  1. データの単位をfield、fieldの列をrecordと呼ぶ。
  2. fieldの区切りはカンマ(,)、recordの区切りは復帰(CR)改行(LF)である。
  3. fieldはその全体を二重引用符(")で囲んでもよい。二重引用符で囲むことを"escapeする"という。
  4. fieldがカンマ/二重引用符/復帰/改行を含むとき、そのfieldはescapeしなければならない。
  5. escapeされたfield中の二重引用符は2つ並べよ(つまりfield内の"は""とし、さらに全体を"で囲め)。

 とまぁ、ざっくりこの程度のルールが定められています。さきほどのExcelシートをCSVで保存したところ:

図2 CSV
図2 CSV

 こんなCSVが得られました。RFC4180に従ったフォーマットになっているようです。

 で、昼メシの賭かったアプリケーションではこのCSV形式のテキストファイルを読み込んで文字列の二次元配列、例えば string[][] や vector<vector<string>> を生成するのが最初の処理となります。

 前述のとおり、RFC4180は言わば"後付け"の規格です。アプリケーションが吐いたCSVがRFC4180に従っていないこともあり得ます。なので少しばかりユルく読み取ることにします。すなわち上記ルールを緩和し、「カンマ/二重引用符/復帰/改行を含むとき、(field全体ではなく)その部分を含む一部をescapeしてもよい」とします。例えばfieldの値が apple,orange であるとき apple","orange としてもいい、と。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • επιστημη(エピステーメー)

    C++に首まで浸かったプログラマ。 Microsoft MVP, Visual C++ (2004.01~) だったり わんくま同盟でたまにセッションスピーカやったり 中国茶淹れてにわか茶人を気取ってたり、 あと Facebook とか。 著書: - STL標準講座 (監修) -...

All contents copyright © 2005-2017 Shoeisha Co., Ltd. All rights reserved. ver.1.5