C++读写CSV文件 (一)

2014-11-23 23:55:32 · 作者: · 浏览: 8

发现它只针对文件中的一行读写,而且只能作为一个局部变量使用,或者读,或者写,不能同时兼用,更不能作为类的变量,更别说扩展了。而且,它只支持在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
#include
#include
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>,而是vector >。
*/
const int ReadCsvData(LPCTSTR lpszFilename, vector > &vlStr);
/*
* 函数功能:将容器中的内容经过排版、布局、添加分隔符后写入到CSV文件。
* 参数描述:
* [in] lpszFilename - 待读取的CSV文件;
* [in] vlStr - 存储分析后的CSV内容
* 返回值:
* 错误代码
* 注意:这里因为特殊愿意(目前还不清楚),不是vector>,而是vector >。
*/
const int WriteCsvData(LPCTSTR lpszFilename, const vector > &vlStr);


private:


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


};


#endif

XCFileStream.cpp


/// 隐藏依赖文件
/// C系统文件
/// C++系统文件
#include /// 读取映射文件
#include
/// 其它库头文件
/// 本项目头文件
#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 > &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 _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