最近の世相と夏の暑さでヨメが壊れた

ある日のこと。
日々の疲れと二日酔いからくる頭痛に見舞われた自営業の働くオクサマは頭にアイスノンを巻きながら、
それでもせっせと仕事をしていましたとさ。
そこに相方。苦しむオクサマにひとこといったとさ。
”おなすみたい”
そうそう。真っ青な顔で下膨れで毛がはみ出てて・・・コラ~っ!!!!

異常気象に老後の不安。景気は悪くなる一方。親もお客も患者もみんなモンスターに成り果てた。
そりゃぁ、青くなる。怒りで赤くなりもする。
あわせりゃそうそう、いつのまに・・・。ムラサキの顔になっていた。
この世はおなすなことばかり。

C++/STLでCSVファイルの読み込み

久しぶりのC++/STLネタということで、CSVファイルの読み込みです。
もともと、Apacheが出力するアクセスログの読み込みの為に作ったのですが、せっかくなので、Excelが出力するCSVにも対応しました。
CSVファイルの読み込みは他の言語ならsplit一発でお茶を濁すのですが、カンマ(,)やダブルクオート(”)、改行があるデータにも対応してます。

/**********************************************************************
 CSVファイルの読み込みサンプル
 試したコンパイル環境
    VC++ .NET 2003 / WINDOWS XP Professional 64 bit edition.
    GCC C++ 3.3.6 / glibc 2.3.4 / Vine Linux 4.2
**********************************************************************/

#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>

/**********************************************************************
 クオート文字の定義構造体
**********************************************************************/
struct quote{
    char    start;  // 開始文字
    char    end;    // 終了文字
    char    escape; // エスケープ文字
    quote( char start_, char end_, char escape_) :
         start(start_), end(end_), escape(escape_) {}
};

struct cmpStartQuote : public std::binary_function<quote,char,bool> {
    bool operator()(const quote &l_s1, const char &l_s2) const {
        return l_s1.start == l_s2;
    }
};

/**********************************************************************
 CSVの読取
**********************************************************************/
bool readCSV(
    std::vector< std::string > &result, // 結果格納ベクター
    std::istreambuf_iterator<char> &i,  // 入力文字イテレータ
    std::string &separator,             // 区切り文字
    std::vector<quote> "es)         // クオート文字ベクター
{
    bool retval = false;
    result.clear();
    std::string item;
    char    bc = '\0';
    bool    first = true;
    std::vector<quote>::iterator    ff = quotes.end();

    while ( i != std::istreambuf_iterator<char>() &&
                    (ff != quotes.end() || *i != '\n') ) {
        if ( ff == quotes.end() &&
                            strchr( separator.c_str(), *i) != 0 ) {
            result.push_back(item);
            item.clear();
            first = true;
            retval = true;
        } else {
            if ( first &&
                (ff = find_if( quotes.begin(),
                            quotes.end(),
                            bind2nd( cmpStartQuote(), *i)))
                    != quotes.end() ) {
                first = false;
            } else if ( ff != quotes.end() && ff->end == *i ) {
                if ( ff->end == ff->escape ) {
                    bc = *i++;
                    if ( i == std::istreambuf_iterator<char>() )
                        break;
                    if ( *i == ff->end ) {
                        item.push_back(*i);
                    } else {
                        ff = quotes.end();
                        continue;
                    }
                } else {
                    if ( bc == ff->escape ) {
                        item.push_back(*i);
                    } else {
                        ff = quotes.end();
                    }
                }
            } else {
                item.push_back(*i);
                first = false;
            }
        }
        bc = *i++;
    }
    result.push_back(item);
    if ( i != std::istreambuf_iterator<char>() ) {
        retval = true;
        i++;
    }
    return retval;
}

using namespace std;


int main(int argc, char* argv[])
{
    basic_ifstream<char>        inputFile("access_log");
    istreambuf_iterator<char>   sin(inputFile);
    vector< string >            rec;

    // APACHEのアクセスログ
    string                      separator(" ");
    vector< quote >             quotes;

    // クオート文字(")の設定("を表示したいときは\"になる)
    quotes.push_back( quote( '"', '"', '\\') );
    // 時間部分のクオート文字([]で括る)
    quotes.push_back( quote( '[', ']', 0 ) );

    while ( readCSV( rec, sin, separator, quotes) ) {
        vector< string >::iterator i;
        for ( i = rec.begin(); i < rec.end(); i++ ) {
            cout << i - rec.begin() << ":" << *i << endl;
        }
        cout << endl;
    }

    return 0;
}

 
上記コードは、Apacheのログを読み込むサンプルで、CSVファイルの読み込みの場合は、
separatorとquotesの部分が、
 

    string                      separator(",");
    vector< quote >             quotes;

    quotes.push_back( quote( '"', '"', '"') );

 
になります。

最近のグラフィックカード(RH2400PRO-LE256H)にはHigh Definition Audio デバイスが載っている

何で使用するのか不明だが、最近購入したグラフィックカード(玄人志向のRH2400PRO-LE256H、ATI RadeonHD2400PRO)にAudioデバイスがあり、こいつのインストールではまったのでメモします。
で、このHD2400PROのドライバページには何故かAudioデバイスドライバが無い。
結局、現時点(2008/08/01)では、このページのXP Professional/Homeから ATI All-in-Wonder™ HD Drivers for Windows XP Professional/Home Editionのリンクをたどりドライバを入手した。
(ちなみに2003 Server 64Bit Editionもこのドライバでいけた)