使用boost::spirit实现的CSV文件解析类

boost::spirit真是不错的说。。。。

None.gif#include <iostream>
None.gif#include <iterator>
None.gif#include <vector>
None.gif#include < string>
None.gif
None.gif#include <boost/spirit/core.hpp>
None.gif#include <boost/spirit/iterator/file_iterator.hpp>
None.gif
None.gif using  namespace std;
None.gif using  namespace boost::spirit;
None.gif
None.giftemplate<typename IteratorT>
None.gif struct LineInfo 
ExpandedBlockStart.gif {
InBlock.gif    IteratorT lineIter;
InBlock.gif    size_t lineNum;
InBlock.gif
ExpandedSubBlockStart.gif    LineInfo( IteratorT beg ) : lineIter(beg), lineNum(1) { }
ExpandedBlockEnd.gif};
None.gif
None.giftemplate<typename IteratorT>
None.gif struct NewLine
ExpandedBlockStart.gif {
InBlock.gif    LineInfo<IteratorT>& lineInfo;
ExpandedSubBlockStart.gif    NewLine( LineInfo<IteratorT>& info ) : lineInfo(info) { }
InBlock.gif
InBlock.gif    void operator()(IteratorT first, IteratorT last) const
ExpandedSubBlockStart.gif    {
InBlock.gif        lineInfo.lineIter = last;
InBlock.gif        lineInfo.lineNum++;
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif};
None.gif
None.gif struct AddVal
ExpandedBlockStart.gif {
InBlock.gif    vector<string>& values;
ExpandedSubBlockStart.gif    AddVal( vector<string>& vec ) : values(vec) { }
InBlock.gif
InBlock.gif    template<class IteratorT>
InBlock.gif    void operator()(IteratorT first, IteratorT last) const
ExpandedSubBlockStart.gif    {
InBlock.gif#ifdef _MSC_VER
InBlock.gif        string s;
InBlock.gif        s.resize(distance(first, last));
InBlock.gif        for (size_t i = 0; first != last; ++i) 
ExpandedSubBlockStart.gif        {
InBlock.gif            s[i] = *first++;
ExpandedSubBlockEnd.gif        }
InBlock.gif#else
InBlock.gif        string s( first, last );
InBlock.gif#endif
InBlock.gif        string::size_type pos = 0;
InBlock.gif        while (1)
ExpandedSubBlockStart.gif        {
InBlock.gif            pos = s.find("\"\"", pos);
InBlock.gif            if (pos == string::npos)
InBlock.gif                break;
InBlock.gif            ++pos;
InBlock.gif            s.erase(pos, 1);
ExpandedSubBlockEnd.gif        }
InBlock.gif        values.push_back(s);
ExpandedSubBlockEnd.gif    }
ExpandedBlockEnd.gif};
None.gif
None.giftemplate< class IteratorT>
None.gif struct CSVParser :  public grammar<CSVParser<IteratorT> >
ExpandedBlockStart.gif {
InBlock.gif    vector<string>& v;
InBlock.gif    LineInfo<IteratorT>& lineInfo;
InBlock.gif
ExpandedSubBlockStart.gif    CSVParser( vector<string>& vec, LineInfo<IteratorT>& info ) : v(vec), lineInfo(info) { }
InBlock.gif
InBlock.gif    template <typename ScannerT>
InBlock.gif    struct definition 
ExpandedSubBlockStart.gif    {
InBlock.gif        rule<ScannerT> csv, val, quoted_val, naked_val;
InBlock.gif
InBlock.gif        definition(const CSVParser<IteratorT>& self)
ExpandedSubBlockStart.gif        {
InBlock.gif            csv = val >> *(',' >> val) >>
InBlock.gif                (eol_p[NewLine<IteratorT>(self.lineInfo)] | end_p);
InBlock.gif
InBlock.gif            val = *blank_p >>
InBlock.gif                ch_p('\"') >> quoted_val[AddVal(self.v)] >> ch_p('\"') >>
InBlock.gif                *blank_p
InBlock.gif                | naked_val[AddVal(self.v)];
InBlock.gif
InBlock.gif            quoted_val = *(eol_p[NewLine<IteratorT>(self.lineInfo)]
InBlock.gif            | ~ch_p('"') | str_p("\"\""));
InBlock.gif
InBlock.gif            naked_val = *(~ch_p(',') & ~ch_p('\"') & ~ch_p('\n'));
ExpandedSubBlockEnd.gif        }
InBlock.gif
ExpandedSubBlockStart.gif        const rule<ScannerT>& start() const { return csv; }
ExpandedSubBlockEnd.gif    };
ExpandedBlockEnd.gif};
None.gif
None.giftemplate<typename IteratorT>
None.gifparse_info<IteratorT>
None.gifparse_csv(  const IteratorT& first,  const IteratorT& last,
None.gif          vector< string>& vec, LineInfo<IteratorT>& info )
ExpandedBlockStart.gif {
InBlock.gif    CSVParser<IteratorT> csv(vec, info);
InBlock.gif
InBlock.gif    return parse(first, last, csv);
ExpandedBlockEnd.gif}
None.gif
None.gif int main(  int argc,  char** argv)
ExpandedBlockStart.gif {
InBlock.gif    if (argc != 2) return 1;
InBlock.gif
InBlock.gif    typedef file_iterator<char> iterator_t;
InBlock.gif
InBlock.gif    iterator_t begin(argv[1]);
InBlock.gif    if (!begin)
ExpandedSubBlockStart.gif    {
InBlock.gif        cout << "Unable to open file: " << argv[1] << endl;
InBlock.gif        return -1;
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    iterator_t first = begin;
InBlock.gif
InBlock.gif    iterator_t last = first.make_end();
InBlock.gif
InBlock.gif    LineInfo<iterator_t> line_info( begin );
InBlock.gif    while ( first != last )
ExpandedSubBlockStart.gif    {
InBlock.gif        vector<string> v;
InBlock.gif        parse_info<iterator_t> info = parse_csv( first, last, v, line_info );
InBlock.gif
InBlock.gif        if (!info.hit)
ExpandedSubBlockStart.gif        {
InBlock.gif            cout << "Error!!  Line: " << line_info.lineNum
InBlock.gif                << ", Column: " << distance(line_info.lineIter, info.stop)+1 << endl;
InBlock.gif            break;
ExpandedSubBlockEnd.gif        }
InBlock.gif
InBlock.gif        cout << "Parses OK:" << endl;
InBlock.gif        for (vector<string>::size_type i = 0; i < v.size(); ++i)
InBlock.gif            cout << i+1 << ": " << v[i] << endl;
InBlock.gif
InBlock.gif        cout << "-------------------------\n";
InBlock.gif
InBlock.gif        first = info.stop;
ExpandedSubBlockEnd.gif    }
InBlock.gif
InBlock.gif    return 0;
ExpandedBlockEnd.gif}
None.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值