文章分类

站点统计

  • 分类总数: 13 个
  • 文章总数: 145 篇
  • 评论总数: 47 条
  • 附件总数: 59 个
  • 建站日期: 2008-08-18
  • 访问总数: 472869 人次
  • RSS订阅: 文章|评论

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

Admin 于 2008-09-13 02:50:57 发表C/C++

订阅: http://www.kaiyuan8.org/Feed/Article_39.aspx
引用: 点这里获取地址 (UTF-8)
两个CSV 解析类 < 使用boost::spirit实现的CSV文件解析类 > 利用飞信虚拟框架开发绿色.NET程序

  1. #include <iostream> 
  2. #include <iterator> 
  3. #include <vector> 
  4. #include <string> 
  5.  
  6. #include <boost/spirit/core.hpp> 
  7. #include <boost/spirit/iterator/file_iterator.hpp> 
  8.  
  9. using namespace std; 
  10. using namespace boost::spirit; 
  11.  
  12. template<typename IteratorT> 
  13. struct LineInfo  
  14.     IteratorT lineIter; 
  15.     size_t lineNum; 
  16.  
  17.     LineInfo( IteratorT beg ) : lineIter(beg), lineNum(1) { } 
  18. }; 
  19.  
  20. template<typename IteratorT> 
  21. struct NewLine 
  22.     LineInfo<IteratorT>& lineInfo; 
  23.     NewLine( LineInfo<IteratorT>& info ) : lineInfo(info) { } 
  24.  
  25.     void operator()(IteratorT first, IteratorT last) const 
  26.     { 
  27.         lineInfo.lineIter = last; 
  28.         lineInfo.lineNum++; 
  29.     } 
  30. }; 
  31.  
  32. struct AddVal 
  33.     vector<string>& values; 
  34.     AddVal( vector<string>& vec ) : values(vec) { } 
  35.  
  36.     template<class IteratorT> 
  37.     void operator()(IteratorT first, IteratorT last) const 
  38.     { 
  39. #ifdef _MSC_VER 
  40.         string s; 
  41.         s.resize(distance(first, last)); 
  42.         for (size_t i = 0; first != last; ++i)  
  43.         { 
  44.             s[i] = *first++; 
  45.         } 
  46. #else 
  47.         string s( first, last ); 
  48. #endif 
  49.         string::size_type pos = 0; 
  50.         while (1) 
  51.         { 
  52.             pos = s.find("\"\"", pos); 
  53.             if (pos == string::npos) 
  54.                 break
  55.             ++pos; 
  56.             s.erase(pos, 1); 
  57.         } 
  58.         values.push_back(s); 
  59.     } 
  60. }; 
  61.  
  62. template<class IteratorT> 
  63. struct CSVParser : public grammar<CSVParser<IteratorT> > 
  64.     vector<string>& v; 
  65.     LineInfo<IteratorT>& lineInfo; 
  66.  
  67.     CSVParser( vector<string>& vec, LineInfo<IteratorT>& info ) : v(vec), lineInfo(info) { } 
  68.  
  69.     template <typename ScannerT> 
  70.     struct definition  
  71.     { 
  72.         rule<ScannerT> csv, val, quoted_val, naked_val; 
  73.  
  74.         definition(const CSVParser<IteratorT>& self) 
  75.         { 
  76.             csv = val >> *(',' >> val) >> 
  77.                 (eol_p[NewLine<IteratorT>(self.lineInfo)] | end_p); 
  78.  
  79.             val = *blank_p >> 
  80.                 ch_p('\"') >> quoted_val[AddVal(self.v)] >> ch_p('\"') >> 
  81.                 *blank_p 
  82.                 | naked_val[AddVal(self.v)]; 
  83.  
  84.             quoted_val = *(eol_p[NewLine<IteratorT>(self.lineInfo)] 
  85.             | ~ch_p('"') | str_p("\"\"")); 
  86.  
  87.             naked_val = *(~ch_p(',') & ~ch_p('\"') & ~ch_p('\n')); 
  88.         } 
  89.  
  90.         const rule<ScannerT>& start() const { return csv; } 
  91.     }; 
  92. }; 
  93.  
  94. template<typename IteratorT> 
  95. parse_info<IteratorT> 
  96. parse_csv( const IteratorT& first, const IteratorT& last, 
  97.           vector<string>& vec, LineInfo<IteratorT>& info ) 
  98.     CSVParser<IteratorT> csv(vec, info); 
  99.  
  100.     return parse(first, last, csv); 
  101.  
  102. int main( int argc, char** argv) 
  103.     if (argc != 2) return 1; 
  104.  
  105.     typedef file_iterator<char> iterator_t; 
  106.  
  107.     iterator_t begin(argv[1]); 
  108.     if (!begin) 
  109.     { 
  110.         cout << "Unable to open file: " << argv[1] << endl; 
  111.         return -1; 
  112.     } 
  113.  
  114.     iterator_t first = begin; 
  115.  
  116.     iterator_t last = first.make_end(); 
  117.  
  118.     LineInfo<iterator_t> line_info( begin ); 
  119.     while ( first != last ) 
  120.     { 
  121.         vector<string> v; 
  122.         parse_info<iterator_t> info = parse_csv( first, last, v, line_info ); 
  123.  
  124.         if (!info.hit) 
  125.         { 
  126.             cout << "Error!!  Line: " << line_info.lineNum 
  127.                 << ", Column: " << distance(line_info.lineIter, info.stop)+1 << endl; 
  128.             break
  129.         } 
  130.  
  131.         cout << "Parses OK:" << endl; 
  132.         for (vector<string>::size_type i = 0; i < v.size(); ++i) 
  133.             cout << i+1 << ": " << v[i] << endl; 
  134.  
  135.         cout << "-------------------------\n"
  136.  
  137.         first = info.stop; 
  138.     } 
  139.  
  140.     return 0; 

 

被阅532次, 0投一票CSV boost spirit
  • 看完了要说点啥么?
  • 昵称 (不填说不了话)
  • 信箱地址 (不会被公开,但是不填也说不了话)
  • 网址 (这个不填也成)
Powered by MiniBoke v2.0.0.8 Build 0828

Copyright © 2008 开源吧!. All rights reserved.

粤ICP备07500939号