C++导入导出CSV文件

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

void csvline_populate(vector<string> &record, const string& line, char delimiter);

int main(int argc, char *argv[])
{
    vector<string> row;
    string line;
    ifstream in("input.csv");
    if (in.fail())  { cout << "File not found" <<endl; return 0; }
     
    while(getline(in, line)  && in.good() )
    {
        csvline_populate(row, line, ',');
        for(int i=0, leng=row.size(); i<leng; i++)
            cout << row[i] << "\t";
        cout << endl;
    }
    in.close();
    return 0;
}

void csvline_populate(vector<string> &record, const string& line, char delimiter)
{
    int linepos=0;
    int inquotes=false;
    char c;
    int i;
    int linemax=line.length();
    string curstring;
    record.clear();
       
    while(line[linepos]!=0 && linepos < linemax)
    {
       
        c = line[linepos];
       
        if (!inquotes && curstring.length()==0 && c=='"')
        {
            //beginquotechar
            inquotes=true;
        }
        else if (inquotes && c=='"')
        {
            //quotechar
            if ( (linepos+1 <linemax) && (line[linepos+1]=='"') )
            {
                //encountered 2 double quotes in a row (resolves to 1 double quote)
                curstring.push_back(c);
                linepos++;
            }
            else
            {
                //endquotechar
                inquotes=false;
            }
        }
        else if (!inquotes && c==delimiter)
        {
            //end of field
            record.push_back( curstring );
            curstring="";
        }
        else if (!inquotes && (c=='\r' || c=='\n') )
        {
            record.push_back( curstring );
            return;
        }
        else
        {
            curstring.push_back(c);
        }
        linepos++;
    }
    record.push_back( curstring );
    return;
}
http://www.zedwood.com/article/112/cpp-csv-parser


6.2.4  CSV文件的读取

CSV即Comma Separated Values(以逗号分隔的值),这种文件格式经常用来作为不同程序之间的数据交互的格式。具体文件格式如下。

每条记录占一行。

记录间的值以逗号为分隔符。

逗号前后的空白字符会被忽略。

如果值中包含逗号、换行符、空格、双引号,则该值必须用双引号引起来。

值中的双引号用两个双引号表示。

如下是一段标准的CSV数据,它来自于某次科学实验的采集记录:

  1. 1993,124,0,13.9,11.2,7.9,5.2,3.7,2.8,2.7,3.0,0.0,0.0  
  2. 1993,125,1,14.2,11.4,8.0,5.3,3.8,2.8,2.7,3.0,0.0,0.0  
  3. 1993,126,2,14.4,11.7,8.2,5.4,3.9,2.8,2.7,3.0,0.0,0.0  
  4. 1993,127,3,13.7,11.1,7.7,5.1,3.6,2.6,2.6,2.9,0.0,0.0  
  5. 1993,128,4,12.9,10.4,7.2,4.7,3.3,2.4,2.4,2.8,0.0,0.0  
  6. 1993,129,5,12.1,9.7,6.6,4.2,2.9,2.2,2.3,2.7,0.0,0.0  
  7. 1993,130,6,12.3,9.9,6.8,4.3,3.0,2.2,2.3,2.7,0.0,0.0  
  8. 1993,131,7,12.0,9.6,6.6,4.2,2.9,2.1,2.2,2.7,0.0,0.0  
  9. 1993,132,8,12.6,10.1,7.0,4.5,3.1,2.2,2.3,2.7,0.0,0.0 

将该段数据保存为某个文件,如:test.csv。Microsoft Excel支持CSV文件格式,图6-12示出在Microsoft Excel中打开test.csv的情形。

 
(点击查看大图)图6-12  在Microsoft Excel中打开test.csv

现在动手

下面我们使用文件流来实现一个CSV文件的读取程序。

选择【Win32】→【Win32项目】→【控制台程序】命令,创建CsvParser。

创建CRow类,它用来描述每一个行的记录。该类实际上是一个CStringArray的代理类:

  1. class CRow  
  2. {  
  3. private:  
  4.     CStringArray * _row;  
  5. public:  
  6.     CRow(CStringArray * row);  
  7.     int getColumnCount(void);  
  8.     CString getColumn(int i);  
  9. };  
  10.  
  11. CRow::CRow(CStringArray * row)  
  12. {  
  13.     _row = row;  
  14. }  
  15.  
  16. int CRow::getColumnCount(void)  
  17. {  
  18.     return _row->GetCount();  
  19. }  
  20.  
  21. CString CRow::getColumn(int i)  
  22. {  
  23.     return _row->GetAt(i);  

创建CSheet类,它用来描述一张表格:

  1. class CSheet  
  2. {  
  3. private:  
  4.     CTypedPtrArray<CPtrArray, CStringArray *> _rows;  
  5. public:  
  6.     CSheet(void);  
  7.     ~CSheet(void);  
  8.     int loadFrom(ifstream & in);  
  9.     int getRowCount(void);  
  10.     CRow getRow(int i);  
  11. };  
  12.  
  13. CSheet::CSheet()  
  14. {  
  15. }  
  16.  
  17. CSheet::~CSheet()  
  18. {  
  19.     for(int i = 0; i < _rows.GetCount(); i++)  
  20.     {  
  21.         delete _rows.GetAt(i);  
  22.     }  
  23. }  
  24.  
  25. int CSheet::loadFrom(ifstream & in)  
  26. {  
  27.     int lines = 0;  
  28.  
  29.     while(!in.eof())  
  30.     {  
  31.         //读取其中的一行  
  32.         char line[256] = {0};  
  33.         in.getline(line, 255);  
  34.  
  35.         CString s = line;  
  36.  
  37.         //空白行,跳过  
  38.         if(s.IsEmpty())  
  39.             continue;  
  40.  
  41.         //#为注释标记,跳过  
  42.         if(s[0] == '#')  
  43.             continue;  
  44.  
  45.         CStringArray *pRow = new CStringArray();  
  46.         int i = 0;  
  47.         CString token = s.Tokenize(_T(",\t"), i);   
  48.         while (token != _T(""))  
  49.         {  
  50.             pRow->Add(token);  
  51.             token = s.Tokenize(_T(",\t"), i);  
  52.         }  
  53.  
  54.         _rows.Add(pRow);  
  55.         lines++;  
  56.     }  
  57.  
  58.     return lines;  
  59. }  
  60.  
  61. int CSheet::getRowCount(void)  
  62. {  
  63.     return _rows.GetCount();  
  64. }  
  65.  
  66. CRow CSheet::getRow(int i)  
  67. {  
  68.     return CRow(_rows.GetAt(i));  

修改主程序如下:

  1. #include "stdafx.h"  
  2. #include "sheet.h"  
  3. #include <iostream>  
  4. #include <fstream>  
  5.  
  6. using namespace std;  
  7.  
  8. int main()  
  9. {  
  10.     CSheet sheet;  
  11.  
  12.     //打开csv文件  
  13.     ifstream in("test.csv");  
  14.     //加载至CSheet  
  15.     sheet.loadFrom(in);  
  16.  
  17.     for(int i = 0; i < sheet.getRowCount(); i++)  
  18.     {  
  19.         _tprintf(_T("[%02d] "), i);  
  20.         //获取指定行  
  21.         CRow row = sheet.getRow(i);  
  22.         for(int j = 0; j < row.getColumnCount(); j++)  
  23.         {  
  24.             //获取指定列  
  25.             CString s = row.getColumn(j);  
  26.             _tprintf(_T("%s/"), s);  
  27.         }  
  28.         _tprintf(_T("\r\n"), i);  
  29.     }  
  30.  
  31.     return 0;  

运行结果如图6-13所示。

 
(点击查看大图)图6-13  运行结果

 

当然,本程序考虑的情况还是不够完善的,希望读者能够结合该实例完善CSV文本文件的解析。

http://book.51cto.com/art/200908/145788.htm

posted on 2009-09-04 13:39  周伟  阅读(4671)  评论(0编辑  收藏  举报

导航