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

简介:
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;
}

目录
相关文章
|
Java 开发者
重学Java基础篇—Java类加载顺序深度解析
本文全面解析Java类的生命周期与加载顺序,涵盖从加载到卸载的七个阶段,并深入探讨初始化阶段的执行规则。通过单类、继承体系的实例分析,明确静态与实例初始化的顺序。同时,列举六种触发初始化的场景及特殊场景处理(如接口初始化)。提供类加载完整流程图与记忆口诀,助于理解复杂初始化逻辑。此外,针对空指针异常等问题提出排查方案,并给出最佳实践建议,帮助开发者优化程序设计、定位BUG及理解框架机制。最后扩展讲解类加载器层次与双亲委派机制,为深入研究奠定基础。
552 0
|
数据可视化 数据挖掘 BI
团队管理者必读:高效看板类协同软件的功能解析
在现代职场中,团队协作的效率直接影响项目成败。看板类协同软件通过可视化界面,帮助团队清晰规划任务、追踪进度,提高协作效率。本文介绍看板类软件的优势,并推荐五款优质工具:板栗看板、Trello、Monday.com、ClickUp 和 Asana,助力团队实现高效管理。
455 2
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
存储 监控 安全
重学Java基础篇—类的生命周期深度解析
本文全面解析了Java类的生命周期,涵盖加载、验证、准备、解析、初始化、使用及卸载七个关键阶段。通过分阶段执行机制详解(如加载阶段的触发条件与技术实现),结合方法调用机制、内存回收保护等使用阶段特性,以及卸载条件和特殊场景处理,帮助开发者深入理解JVM运作原理。同时,文章探讨了性能优化建议、典型异常处理及新一代JVM特性(如元空间与模块化系统)。总结中强调安全优先、延迟加载与动态扩展的设计思想,并提供开发建议与进阶方向,助力解决性能调优、内存泄漏排查及框架设计等问题。
667 5
|
安全 IDE Java
重学Java基础篇—Java Object类常用方法深度解析
Java中,Object类作为所有类的超类,提供了多个核心方法以支持对象的基本行为。其中,`toString()`用于对象的字符串表示,重写时应包含关键信息;`equals()`与`hashCode()`需成对重写,确保对象等价判断的一致性;`getClass()`用于运行时类型识别;`clone()`实现对象复制,需区分浅拷贝与深拷贝;`wait()/notify()`支持线程协作。此外,`finalize()`已过时,建议使用更安全的资源管理方式。合理运用这些方法,并遵循最佳实践,可提升代码质量与健壮性。
539 1
|
Java 数据库 开发者
详细介绍SpringBoot启动流程及配置类解析原理
通过对 Spring Boot 启动流程及配置类解析原理的深入分析,我们可以看到 Spring Boot 在启动时的灵活性和可扩展性。理解这些机制不仅有助于开发者更好地使用 Spring Boot 进行应用开发,还能够在面对问题时,迅速定位和解决问题。希望本文能为您在 Spring Boot 开发过程中提供有效的指导和帮助。
2470 12
|
传感器 监控 Java
Java代码结构解析:类、方法、主函数(1分钟解剖室)
### Java代码结构简介 掌握Java代码结构如同拥有程序世界的建筑蓝图,类、方法和主函数构成“黄金三角”。类是独立的容器,承载成员变量和方法;方法实现特定功能,参数控制输入环境;主函数是程序入口。常见错误包括类名与文件名不匹配、忘记static修饰符和花括号未闭合。通过实战案例学习电商系统、游戏角色控制和物联网设备监控,理解类的作用、方法类型和主函数任务,避免典型错误,逐步提升编程能力。 **脑图速记法**:类如太空站,方法即舱段;main是发射台,static不能换;文件名对仗,括号要成双;参数是坐标,void不返航。
627 5
|
机器学习/深度学习 人工智能 监控
鸿蒙赋能智慧物流:AI类目标签技术深度解析与实践
在数字化浪潮下,物流行业面临变革,传统模式的局限性凸显。AI技术为物流转型升级注入动力。本文聚焦HarmonyOS NEXT API 12及以上版本,探讨如何利用AI类目标签技术提升智慧物流效率、准确性和成本控制。通过高效数据处理、实时监控和动态调整,AI技术显著优于传统方式。鸿蒙系统的分布式软总线技术和隐私保护机制为智慧物流提供了坚实基础。从仓储管理到运输监控再到配送优化,AI类目标签技术助力物流全流程智能化,提高客户满意度并降低成本。开发者可借助深度学习框架和鸿蒙系统特性,开发创新应用,推动物流行业智能化升级。
517 1
|
安全 编译器 C语言
【C++篇】深度解析类与对象(中)
在上一篇博客中,我们学习了C++类与对象的基础内容。这一次,我们将深入探讨C++类的关键特性,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载、以及取地址运算符的重载。这些内容是理解面向对象编程的关键,也帮助我们更好地掌握C++内存管理的细节和编码的高级技巧。
|
存储 程序员 C语言
【C++篇】深度解析类与对象(上)
在C++中,类和对象是面向对象编程的基础组成部分。通过类,程序员可以对现实世界的实体进行模拟和抽象。类的基本概念包括成员变量、成员函数、访问控制等。本篇博客将介绍C++类与对象的基础知识,为后续学习打下良好的基础。

推荐镜像

更多
  • DNS