程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++讀寫CSV文件

C++讀寫CSV文件

編輯:C++入門知識

發現它只針對文件中的一行讀寫,而且只能作為一個局部變量使用,或者讀,或者寫,不能同時兼用,更不能作為類的變量,更別說擴展了。而且,它只支持在MFC條件下實現,如果我們需要在一個模塊當中呢?在一個庫中呢?在非MFC中呢?不過,它的讀取遍歷算法和寫入算法我覺得還是不錯的,所以,基於此,也根據我自己工作中的需求做了改變,也在測試中達到了比較好的結果。

 


一般讀取CSV文件我們是需要:

1、既能滿足MFC,又能滿足非MFC;

2、逐行讀取,而不是一行,因為可能不止一行;

3、讀取一行後需要針對分隔符(一般是“,”)來分析獲得所有解析後的元素項,而且每一行的元素個數都不一定相同;

4、寫入CSV時,針對每一行的元素之間都要添加分隔符(一般是“,”),甚至元素當中可能有諸如:冒號(“"”)、逗號(“,”)這樣比較特殊的字符,我們又如何解決呢?

5、作為一個封裝類,留有余地便於今後的完善和擴展。

 


好了,不多說了,上代碼:

 


XCFileStream.h

 


#if _MSC_VER > 1000
#pragma once
#endif


#ifndef __XCFILESTREAM_H__
#define __XCFILESTREAM_H__


/// 隱藏依賴文件
/// C系統文件
/// C++系統文件
#include <string>
#include <list>
#include <vector>
using namespace std;
#include <windows.h>
/// 其它庫頭文件
/// 本項目頭文件


/// 無錯
#define XC_ERR_NONE 0
/// 無效文件名或非指定文件格式
#define XC_ERR_INVALID_FILE_NAME (-1)


/// xun-test文件的讀與寫
class CXCFileStream
{


public:


CXCFileStream(void);
~CXCFileStream(void);


/*
* 函數功能:讀取CSV文件,分析其中的內容,然後存儲在容器中。
* 參數描述:
*     [in] lpszFilename - 待讀取的CSV文件;
*     [in, out] vlStr - 存儲分析後的CSV內容
* 返回值:
*     錯誤代碼
* 注意:這裡因為特殊願意(目前還不清楚),不是vector<list<string>>,而是vector<list<string> >。
*/
const int ReadCsvData(LPCTSTR lpszFilename, vector<list<string> > &vlStr);
/*
* 函數功能:將容器中的內容經過排版、布局、添加分隔符後寫入到CSV文件。
* 參數描述:
*     [in] lpszFilename - 待讀取的CSV文件;
*     [in] vlStr - 存儲分析後的CSV內容
* 返回值:
*     錯誤代碼
* 注意:這裡因為特殊願意(目前還不清楚),不是vector<list<string>>,而是vector<list<string> >。
*/
const int WriteCsvData(LPCTSTR lpszFilename, const vector<list<string> > &vlStr);


private:


/// 判斷是否是CSV文件
const bool IsCsvFile(LPCTSTR lpszFilename);


};


#endif

 

 

XCFileStream.cpp

 


/// 隱藏依賴文件
/// C系統文件
/// C++系統文件
#include <fstream> /// 讀取映射文件
#include <algorithm>
/// 其它庫頭文件
/// 本項目頭文件
#include "XCFileStream.h"


CXCFileStream::CXCFileStream()
{
}


CXCFileStream::~CXCFileStream(void)
{
}


const bool CXCFileStream::IsCsvFile(LPCTSTR lpszFilename)
{
/// 0、判斷文件名是否有效
if (NULL == lpszFilename || 4 > strlen(lpszFilename))
return false;
/// 本地變量
string _strFileName(lpszFilename);
size_t _iLen = _strFileName.length();
string _strSuff(_strFileName.substr(_iLen - 4, 4));
/// 轉變為小寫,如果要轉變為大寫:tolower -> toupper 。
transform(_strSuff.begin(), _strSuff.end(), _strSuff.begin(), tolower);
/// 1、判斷是否是CSV文件
return (0 == _strSuff.compare(".csv"));
}


const int CXCFileStream::ReadCsvData(LPCTSTR lpszFilename, vector<list<string> > &vlStr)
{
/// 1、判斷是否是CSV文件
if (! IsCsvFile(lpszFilename))
return XC_ERR_INVALID_FILE_NAME;
/// 2、打開CSV文件
ifstream _streamFromFile(lpszFilename);
///    判斷打開文件是否成功
if (NULL == _streamFromFile)
return (-errno);
/// 存儲讀取的文件內容
string _strIn("");
/// 3、讀取一行
while (getline(_streamFromFile, _strIn)) {
/// 每行的源字符串
LPCTSTR _pcSrc = _strIn.c_str();
/// 存儲一行‘,'分隔解析後的各個元素
list<string> _ltStr;
/// Parse values in this line
while (*_pcSrc != '\0') {
/// string to hold this value
string _strElem("");
/// 針對每個字符分析
if (*_pcSrc == '"') {
/// Bump past opening quote
_pcSrc++;
/// Parse quoted value
while (*_pcSrc != '\0') {
/// Test for quote character
if (*_pcSrc == '"') {
/// Found one quote
_pcSrc++;
// If pair of quotes, keep one
// Else interpret as end of value
if (*_pcSrc != '"') {
_pcSrc++;
break;
}
}
/// Add this character to value
_strElem.push_back(*_pcSrc++);
}
}
else {
// Parse unquoted value
while (*_pcSrc != '\0' && *_pcSrc != ',')
_strElem.push_back(*_pcSrc++);
// Advance to next character (if not already end of string)
if (*_pcSrc != '\0')
_pcSrc++;
}
/// Add this string to container
_ltStr.push_back(_strElem);
}
/// 分析後的一行文件內容所得的元素列表添加到容器中
vlStr.push_back(_ltStr);
/// 歸零,防止下次分析舊的數據。
_strIn.assign("");
}


return XC_ERR_NONE;
}


const int CXCFileStream::WriteCsvData(LPCTSTR lpszFilename, const vector<list<string> > &vlStr)
{
/// 1、判斷是否是CSV文件
if (! IsCsvFile(lpszFilename))
return XC_ERR_INVALID_FILE_NAME;
/// 2、打開CSV文件
ofstream _streamToFile(lpszFilename);
///    判斷打開文件是否成功
if (NULL == _streamToFile)
return (-errno);
/// 本地變量
static TCHAR chQuote = '"';
static TCHAR chComma = ',';
/// Loop through each list of string in vector
for (vector<list<string> >::const_iterator vIt = vlStr.begin(); vIt != vlStr.end(); vIt ++) {
/// Loop through each string in list
for (list<string>::const_iterator lIt = vIt->begin(); lIt != vIt->end(); lIt ++) {
/// Separate this value from previous
if (vIt->begin() != lIt)
_streamToFile.put(chComma);
/// 考慮string中可能有,或"的情況,這就要特殊包裝。
bool bComma = (lIt->find(chComma) != lIt->npos);
bool bQuote = (lIt->find(chQuote) != lIt->npos);
/// 真的含有,或"的情況
if (bComma || bQuote) {
_streamToFile.put(chQuote);


if (bQuote) {
for (string::const_iterator chIt = lIt->begin(); chIt != lIt->end(); chIt ++ ) {
// Pairs of quotes interpreted as single quote
if (chQuote == *chIt)
_streamToFile.put(chQuote);


_streamToFile.put(*chIt);
}
}
else
_streamToFile << *lIt;


_streamToFile.put(chQuote);
}
else
_streamToFile << *lIt;
}
/// 換行
_streamToFile << endl;
}
///
return XC_ERR_NONE;
}

 

 

如果朋友你有更好的建議或這裡有問題,請根據blog抬頭我的聯系方式跟我取得聯系,感謝你的支持和幫助。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved