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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介:
boost::spirit真是不错的说。。。。

#include <iostream>
#include <iterator>
#include <vector>
#include < string>

#include <boost/spirit/core.hpp>
#include <boost/spirit/iterator/file_iterator.hpp>

using  namespace std;
using  namespace boost::spirit;

template<typename IteratorT>
struct LineInfo 
{
    IteratorT lineIter;
    size_t lineNum;

    LineInfo( IteratorT beg ) : lineIter(beg), lineNum(1) { }
}
;

template<typename IteratorT>
struct NewLine
{
    LineInfo<IteratorT>& lineInfo;
    NewLine( LineInfo<IteratorT>& info ) : lineInfo(info) { }

    void operator()(IteratorT first, IteratorT last) const
    {
        lineInfo.lineIter = last;
        lineInfo.lineNum++;
    }

}
;

struct AddVal
{
    vector<string>& values;
    AddVal( vector<string>& vec ) : values(vec) { }

    template<class IteratorT>
    void operator()(IteratorT first, IteratorT last) const
    {
#ifdef _MSC_VER
        string s;
        s.resize(distance(first, last));
        for (size_t i = 0; first != last; ++i) 
        {
            s[i] = *first++;
        }

#else
        string s( first, last );
#endif
        string::size_type pos = 0;
        while (1)
        {
            pos = s.find("\"\"", pos);
            if (pos == string::npos)
                break;
            ++pos;
            s.erase(pos, 1);
        }

        values.push_back(s);
    }

}
;

template< class IteratorT>
struct CSVParser :  public grammar<CSVParser<IteratorT> >
{
    vector<string>& v;
    LineInfo<IteratorT>& lineInfo;

    CSVParser( vector<string>& vec, LineInfo<IteratorT>& info ) : v(vec), lineInfo(info) { }

    template <typename ScannerT>
    struct definition 
    {
        rule<ScannerT> csv, val, quoted_val, naked_val;

        definition(const CSVParser<IteratorT>& self)
        {
            csv = val >> *(',' >> val) >>
                (eol_p[NewLine<IteratorT>(self.lineInfo)] | end_p);

            val = *blank_p >>
                ch_p('\"') >> quoted_val[AddVal(self.v)] >> ch_p('\"') >>
                *blank_p
                | naked_val[AddVal(self.v)];

            quoted_val = *(eol_p[NewLine<IteratorT>(self.lineInfo)]
            | ~ch_p('"') | str_p("\"\""));

            naked_val = *(~ch_p(',') & ~ch_p('\"') & ~ch_p('\n'));
        }


        const rule<ScannerT>& start() const return csv; }
    }
;
}
;

template<typename IteratorT>
parse_info<IteratorT>
parse_csv(  const IteratorT& first,  const IteratorT& last,
          vector< string>& vec, LineInfo<IteratorT>& info )
{
    CSVParser<IteratorT> csv(vec, info);

    return parse(first, last, csv);
}


int main(  int argc,  char** argv)
{
    if (argc != 2) return 1;

    typedef file_iterator<char> iterator_t;

    iterator_t begin(argv[1]);
    if (!begin)
    {
        cout << "Unable to open file: " << argv[1] << endl;
        return -1;
    }


    iterator_t first = begin;

    iterator_t last = first.make_end();

    LineInfo<iterator_t> line_info( begin );
    while ( first != last )
    {
        vector<string> v;
        parse_info<iterator_t> info = parse_csv( first, last, v, line_info );

        if (!info.hit)
        {
            cout << "Error!!  Line: " << line_info.lineNum
                << ", Column: " << distance(line_info.lineIter, info.stop)+1 << endl;
            break;
        }


        cout << "Parses OK:" << endl;
        for (vector<string>::size_type i = 0; i < v.size(); ++i)
            cout << i+1 << ": " << v[i] << endl;

        cout << "-------------------------\n";

        first = info.stop;
    }


    return 0;
}

目录
相关文章
|
1月前
|
数据处理 开发者 Python
Python 高级编程:深入解析 CSV 文件读取
在Python中,读取CSV文件是数据处理的重要环节。本文介绍了两种高效方法:一是利用pandas库的`read_csv`函数,将CSV文件快速转换为DataFrame对象,便于数据操作;二是通过csv模块的`csv.reader`按行读取CSV内容。此外,还涉及了如何选取特定列、解析日期格式、跳过指定行以及分块读取大文件等高级技巧,帮助开发者更灵活地处理各种CSV文件。参考链接:&lt;https://www.wodianping.com/app/2024-10/48782.html&gt;。
93 6
|
24天前
|
存储 Java API
详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
【10月更文挑战第19天】深入剖析Java Map:不仅是高效存储键值对的数据结构,更是展现设计艺术的典范。本文从基本概念、设计艺术和使用技巧三个方面,详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
41 3
|
5月前
|
缓存 开发者 索引
深入解析 `org.elasticsearch.action.search.SearchRequest` 类
深入解析 `org.elasticsearch.action.search.SearchRequest` 类
|
1月前
|
存储 编译器 数据安全/隐私保护
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解2
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
29 3
|
1月前
|
编译器 C++
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解1
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
45 3
|
1月前
|
程序员 开发者 Python
深度解析Python中的元编程:从装饰器到自定义类创建工具
【10月更文挑战第5天】在现代软件开发中,元编程是一种高级技术,它允许程序员编写能够生成或修改其他程序的代码。这使得开发者可以更灵活地控制和扩展他们的应用逻辑。Python作为一种动态类型语言,提供了丰富的元编程特性,如装饰器、元类以及动态函数和类的创建等。本文将深入探讨这些特性,并通过具体的代码示例来展示如何有效地利用它们。
35 0
|
3月前
|
缓存 Java 开发者
Spring高手之路22——AOP切面类的封装与解析
本篇文章深入解析了Spring AOP的工作机制,包括Advisor和TargetSource的构建与作用。通过详尽的源码分析和实际案例,帮助开发者全面理解AOP的核心技术,提升在实际项目中的应用能力。
45 0
Spring高手之路22——AOP切面类的封装与解析
|
3月前
|
JSON 图形学 数据格式
Json☀️ 一、认识Json是如何解析成类的
Json☀️ 一、认识Json是如何解析成类的
|
3月前
|
开发者 编解码
界面适应奥秘:从自适应布局到图片管理,Xamarin响应式设计全解析
【8月更文挑战第31天】在 Xamarin 的世界里,构建灵活且适应性强的界面是每位开发者的必修课。本文将带您探索 Xamarin 的响应式设计技巧,包括自适应布局、设备服务协商和高效图片管理,帮助您的应用在各种设备上表现出色。通过 Grid 和 StackLayout 实现弹性空间分配,利用 Device 类检测设备类型以加载最优布局,以及使用 Image 控件自动选择合适图片资源,让您轻松应对不同屏幕尺寸的挑战。掌握这些技巧,让您的应用在多变的市场中持续领先。
39 0
|
3月前
|
存储 开发者 Ruby
【揭秘Ruby高手秘籍】OOP编程精髓全解析:玩转类、继承与多态,成就编程大师之路!
【8月更文挑战第31天】面向对象编程(OOP)是通过“对象”来设计软件的编程范式。Ruby作为一种纯面向对象的语言,几乎所有事物都是对象。本文通过具体代码示例介绍了Ruby中OOP的核心概念,包括类与对象、继承、封装、多态及模块混合,展示了如何利用这些技术更好地组织和扩展代码。例如,通过定义类、继承关系及私有方法,可以创建具有特定行为的对象,并实现灵活的方法重写和功能扩展。掌握这些概念有助于提升代码质量和可维护性。
36 0

推荐镜像

更多