系统:WIN7 32位 旗舰版 编译器: VS2010 语言: C++,MFC 说明:事先读写CSV文件,数据格式为vector<list<string>> #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.c文件 #include "StdAfx.h" /// 隐藏依赖文件 /// 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; } //将以上两文件加入自个的工程中 //在需要的地方中加入写CSV函数 vector<list<string>> m_pOrderData;//要写到csv文件的数据 Write2File(CString filePath) { CXCFileStream cs; CString FilePath = _T("C:\\TEST.csv"); //有修改订单时保存到文件 if(m_GridEdit) { cs.WriteCsvData(FilePath, m_pOrderData); } } //读函数 FilePath为所要读的CSV全路径比如:_T("C:\\TEST.csv"); void CMenuD::FromCSV(CString FilePath) { CString temp; CXCFileStream cs; vector<list<string>> ReadData;//内存:存储读取的CSV数据 int ndex = 0; int DataSize = 0; if(0 != cs.ReadCsvData(FilePath, ReadData)) { //读文件出错 } } |
|