zoukankan      html  css  js  c++  java
  • CSV简单解析与排序输出

    读取CSV每一行,每一行内容在解析时可以分为2种情况:1.没扫描到"  2.扫描到"

    情况1:

    直接通过截取内容中的,来分列。例如行内容为: 姓名,年龄,编号  。则可以分为3列

    姓名

    年龄

    编号

    情况2:

    扫描行内容,当扫描到内容的第一个",去掉该",接着扫描

    <1>之后扫描到""则输出"

    <2>其他内容按照原内容输出

    <3>当扫描到单个符号"("之后没有紧接着")则去掉这个",该列扫描完毕。

    最后输出的内容为该列的值。

    例如内容为: """,",","   。则可以分为2列

    ",

    ,

    头文件:

     1 #include<iostream>
     2 #include<fstream>
     3 #include<string>
     4 using namespace std;
     5 
     6 class CCsv
     7 {    
     8 public:
     9     //构造函数
    10     CCsv(void);
    11 
    12     /*******************************************************************
    13     ** 函数名:     Csv_IsCsvFile
    14     ** 函数描述:   判断文件是否是csv文件
    15     ** 参数:       [in] strFileName:           csv文件名
    16     ** 返回:      true,是csv文件;false,不是csv文件
    17     *******************************************************************/
    18     bool Csv_IsCsvFile(const string &strFileName);
    19 
    20     /*******************************************************************
    21     ** 函数名:     Csv_ReadFile
    22     ** 函数描述:   读取CSV文件,并解析内容存放到vvStr,并判断csv文件是否规范
    23     ** 参数:       [in] pFileName:             该csv文件名
    24     **             [in] vvStr:                 用于存放解析内容
    25     ** 返回:      true,解析成功;false,解析失败
    26     *******************************************************************/
    27     bool Csv_ReadFile(const char* pFileName, vector<vector<string> > &vvStr);
    28 
    29     /*******************************************************************
    30     ** 函数名:     Csv_AnalysisCsvLine
    31     ** 函数描述:  解析CSV文件的一行内容,并把该行解析内容放入vvStr
    32     ** 参数:       [in] strContent:            CSV文件的一行内容
    33     **             [in] vvStr:                 用于存放解析内容
    34     ** 返回:      
    35     *******************************************************************/
    36     void Csv_AnalysisCsvLine(const string & strContent, vector<vector<string> > &vvStr);
    37 
    38     /*******************************************************************
    39     ** 函数名:     Csv_ShowCsvContent
    40     ** 函数描述:   输出vvStr所存放的csv解析内容
    41     ** 参数:      [in] vvStr:                 用于存放解析内容
    42     ** 返回:      
    43     *******************************************************************/
    44     void Csv_ShowCsvContent(vector<vector<string> > &vvStr);
    45     
    46     //析构函数
    47     ~CCsv(void);
    48 private:
    49 
    50 };

    主程序:

      1 #include "stdafx.h"
      2 #include <iostream>
      3 #include <string>
      4 #include <vector>
      5 #include <algorithm>
      6 #include "modCsv.h"
      7 using namespace std;
      8 
      9 int g_rows = 0; //记录列下标
     10 const char cQuote = '"'; //定义引号常量 
     11 const char cComma = ','; //定义逗号常量
     12 
     13 //CCsv构造函数
     14 CCsv::CCsv(void)
     15 {
     16 
     17 }
     18 
     19 //CCsv析构函数
     20 CCsv::~CCsv(void)
     21 {
     22 
     23 }
     24 
     25 //判断文件是否为csv文件
     26 //strFileName为文件名
     27 bool CCsv::Csv_IsCsvFile(const string &strFileName)
     28 {
     29     //csv文件最少字符为a.csv,所以当文件名小于5,该文件就不是csv文件
     30     if (strFileName.length()<5)
     31     {
     32         cout<<"该文件不是csv文件!"<<endl;
     33         return false;
     34     }
     35 
     36     string strFileFormat = strFileName.substr(strFileName.length()-4,4);//截取文件的后缀名 .csv
     37     //将文件后缀变为小写
     38     transform(strFileFormat.begin(),strFileFormat.end(),strFileFormat.begin(),::tolower);
     39 
     40     //判断文件名是否是csv文件
     41     if (1 == strFileFormat.compare(".csv"))
     42     {    
     43         cout<<"该文件不是csv文件!"<<endl;
     44         return false;
     45     }
     46 
     47     return true;
     48 }
     49 
     50 //读取并解析CSV文件,并判断csv文件是否规范
     51 //pFileName为该csv文件名, vvStr为用于存放解析内容的变量
     52 bool CCsv::Csv_ReadFile(const char* pFileName, vector<vector<string> > &vvStr)
     53 {
     54     if (pFileName == NULL)
     55     {
     56         return false;
     57     }
     58     //创建输入流
     59     ifstream inCsv(pFileName, ios::in);
     60 
     61     //判断打开文件是否成功
     62     if (!inCsv)
     63     {
     64         cout<<"打开文件失败!
    ";
     65         return false;
     66     }
     67 
     68     //读文件
     69     while (!inCsv.eof())
     70     {    
     71         string lineContent;
     72         inCsv>>lineContent; //行内容暂存到lineContent
     73         //解析该行内容
     74         Csv_AnalysisCsvLine(lineContent,vvStr);
     75     }
     76 
     77     size_t size = vvStr[0].size();//初始每行列数
     78     //循环判断每行的列数是否一样
     79     for (vector<vector<string> >::iterator vvIt = vvStr.begin(); vvIt != vvStr.end(); ++ vvIt)
     80     {
     81         g_rows++;
     82         if ((*vvIt).size() != size)
     83         {
     84             cout<<"该csv文件格式不符合规范:第";
     85             cout<<g_rows<<"行有"<<(*vvIt).size()<<"列,而第一行有"<<size<<""<<endl;
     86             break;
     87         }
     88     }
     89 
     90     //显示解析内容
     91     Csv_ShowCsvContent(vvStr);
     92     return true;
     93 }
     94 
     95 //解析CSV文件的一行内容
     96 void CCsv::Csv_AnalysisCsvLine(const string & strContent, vector<vector<string> > &vvStr)
     97 {
     98     //string *pStrContent =  &strContent;
     99     string strRowContent = "";//初始化列内容为空
    100     vector<string> vRowContent ;//临时vector ,用于最后存入vvStr
    101     
    102     //扫描整行内容
    103     for(size_t i = 0; i < strContent.size(); i++)// i 为size_t而不是int,是由于strContent.size()返回的是unsigned int
    104     {
    105         //当扫描到" ,表示一串字符开始
    106         if (strContent[i] == cQuote)
    107         {    
    108             while (i < strContent.size())
    109             {
    110                 i++;
    111                 if (strContent[i] ==cQuote)
    112                 {    //如果内容为"" ,表示输出转义字符"
    113                     if (strContent[i+1] == cQuote)
    114                     {
    115                         strRowContent += cQuote;
    116                         i = i + 1; //指针往下
    117                     }
    118                     //"后面没有紧接着",表示一列结束,break跳出循环
    119                     else
    120                     {
    121                         break;
    122                     }
    123 
    124                 }
    125                 else
    126                 {
    127                     strRowContent += strContent[i]; //该字符添加入列内容
    128                 }
    129             }
    130             //当扫描结束还是扫描不到"(字符串结束符),则该行的"没有成对存在,不符合csv规则
    131             if (strContent[i] == '')
    132             {
    133                 cout<<"该csv文件格式不符合规范:第"<<(vvStr.size()+1)<<"行的"不匹配"<<endl;
    134             }
    135         }
    136         //当前字符为',' ,表示一列结束
    137         else if (strContent[i] == cComma)
    138         {
    139             //把strRowContent存放的列的内容放入vRowContent
    140             vRowContent.push_back(strRowContent);
    141             strRowContent = "";
    142         }        
    143         else
    144         {
    145             strRowContent += strContent[i]; //该字符添加入列内容
    146         }
    147     }
    148     //把strRowContent存放的列的内容放入vRowContent
    149     vRowContent.push_back(strRowContent);
    150     //把该行所有列的内容村放入vvStr
    151     vvStr.push_back(vRowContent);
    152 }
    153 
    154 //输出 vector<vector<string> > &vvStr 所存放的csv解析内容
    155 void CCsv::Csv_ShowCsvContent(vector<vector<string> > &vvStr)
    156 {
    157     //用迭代方式输出 vector<list<string>> vlStr 所存放的csv解析内容
    158     for (vector<vector<string> >::iterator vvIt = vvStr.begin(); vvIt != vvStr.end(); ++ vvIt)
    159     {
    160         for (vector<string>::iterator vIt = (*vvIt).begin(); vIt != (*vvIt).end(); ++ vIt)
    161         {
    162             cout<<*vIt<<"    ";
    163         }
    164         cout<<endl;
    165     }
    166 }
    167 
    168 bool SortMethod(const vector<string> &vStr1, const vector<string> &vStr2)//本函数的参数的类型一定要与vector中元素的类型一致  
    169 {  
    170     return vStr1[g_rows-1] < vStr2[g_rows-1];//升序排列  
    171 }  
    172 
    173 int main(void)
    174 {
    175     CCsv csv;//定义csv对象
    176     string strFileName = "in.csv";//定义csv的文件名
    177     
    178     //判断文件是否为csv文件,若不是直接结束程序
    179     if(!csv.Csv_IsCsvFile(strFileName))
    180     {
    181         return 0;
    182     }
    183 
    184     const char* pFileName =   &strFileName[0]; //定义要解析的文件名
    185     vector<vector<string> > vvStr ;    //用于存放解析内容
    186     
    187     cout<<"FileName:"<<pFileName<<endl;
    188     
    189     //读取并解析pFileName到vvStr中
    190     csv.Csv_ReadFile(pFileName, vvStr);
    191     
    192     cout<<"输入需要排序的列(";
    193     //用迭代的方式输出列的可选排序项
    194     g_rows = 0;
    195     for (vector<string>::iterator vIt = vvStr[0].begin(); vIt != vvStr[0].end(); ++vIt)
    196     {
    197         cout<<++g_rows<<"."<<*vIt<<"  ";
    198     }
    199     cout<<"):";
    200     
    201     //输入需要排序的列
    202     cin>>g_rows;
    203     
    204     //排序函数
    205     sort((vvStr.begin()+1),vvStr.end(),SortMethod); 
    206 
    207     //显示排序后的csv内容
    208     csv.Csv_ShowCsvContent(vvStr);
    209 
    210     return 1;
    211 }

    新手刚上路,代码还有很多缺陷仍在改进中。。。。。

  • 相关阅读:
    洛谷 P2421 [NOI2002]荒岛野人
    POJ 2115 C Looooops
    POJ 3292 Semi-prime H-numbers
    [网络流24题]负载平衡问题(费用流)
    [网络流24题]骑士共存问题
    POJ 3281 Dining
    洛谷 1306斐波那契公约数
    ELK+Filebeat 安装配置入门
    一个JS内存泄露实例分析
    Node.js 事件循环
  • 原文地址:https://www.cnblogs.com/qq42425328/p/zhen.html
Copyright © 2011-2022 走看看