分享

MFC CSV文件读写

 紫殿 2017-08-10
系统:WIN7 32位 旗舰版
编译器: VS2010
语言: C++,MFC
说明:事先读写CSV文件,数据格式为vector<list<string>>

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.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))
{
//读文件出错
}
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多