#include <stdafx.h>
#include <fstream>
#include <sstream>
#include <iostream>
#include <atlstr.h>
#include <string> // for string and wstring
using namespace std;
#define MAX_ASSIGN_ITEMS 4
#define MAX_FAXDESC 254
#define ABECFG_ENABLE_CJK_INPUT // 能够处理 中日韩文
#pragma region Write-CsvFile
// 初始化写入CSV文件的数据(在这里Demo 就随便写了,实际中一般从其他地方得到)
CString strTextArray[][5] = {
(_T("2")), _T("111"), (_T("424")), _T("dgdfg"), _T("dgdfg"),
(_T("3")), _T("111"), (_T("2")), _T("111"), _T("dgdfg"),
(_T("4")), _T("111"), (_T("2")), _T("111"), _T("dgdfg"),
(_T("5")), _T("111"), (_T("2")), _T("3553"), _T("dgdfg"),
(_T("6")), _T("111"), (_T("2")), _T("111"), _T("dgdfg"),
};
BOOL GetListSeparator(char szSeparator[5])
{
TCHAR szTemp[5];
if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SLIST, szTemp, 5) > 0)
{
#ifdef _UNICODE
WideCharToMultiByte(CP_ACP, 0, (WCHAR*)szTemp, -1,
szSeparator, 5, NULL, NULL );
#else
strcpy_s(szSeparator, 5, szTemp);
#endif
}
else
{
strcpy(szSeparator, ",");
}
return TRUE;
}
bool WriteCsvFileContent(ofstream *pStream)
{
if (pStream == NULL)
{
return FALSE;
}
//char comma = ',';
char szSeparator[5];
GetListSeparator(szSeparator);
char splitchar=szSeparator[0];
char szText[MAX_FAXDESC];
std::wostringstream oss;
TCHAR szTemp[5];
wstring strSplitW;
if(GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SLIST, szTemp, 5)>0)
{
strSplitW=szTemp;
}
else
{
strSplitW=L",";
}
strSplitW=L"\t";
for (int i = 0; i < sizeof(strTextArray)/sizeof(strTextArray[0]); ++i)
{
for (int j = 0; j < sizeof(strTextArray[0])/sizeof(strTextArray[0][0]); ++j)
{
CString strText = strTextArray[i][j];
oss.str(L"");
oss<<strText.GetBuffer();
strText.ReleaseBuffer();
std::wstring wstr=oss.str().c_str();
//#if defined(CM215F) || defined(CM215FW) || defined(FX_M218FW) || defined(FX_M215FW)
#if defined(ABECFG_ENABLE_CJK_INPUT)
WideCharToMultiByte(/*932*/CP_UTF8, 0, strText.GetBuffer(), -1, szText, MAX_FAXDESC, NULL, NULL); // Enforce Japanese Codepage
strText.ReleaseBuffer();
#else
#ifdef _UNICODE
WideCharToMultiByte(CP_ACP, 0, strText.GetBuffer(), -1, szText, MAX_FAXDESC, NULL, NULL);
strText.ReleaseBuffer();
#else
strcpy(szText, strText);
#endif
#endif
if (strlen(szText) > 0)
{
//pStream->write(szText, strlen(szText));
pStream->write((char*)oss.str().c_str(),oss.str().length()*sizeof(wchar_t));
}
else
{
//pStream->write("", 1);
}
pStream->write((char*)strSplitW.c_str(),sizeof(wchar_t)*strSplitW.length());
}
// 写完一行,进行回车换行
pStream->write((char*)L"\r\n",4);
pStream->flush();
}
pStream->write((char*)L"\r\n",4);
pStream->flush();
return TRUE;
}
// 写 CSV 文件
bool WriteCsvFile(CString _strDstPath)
{
ofstream file;
file.open(_strDstPath,std::ios::out|std::ios::binary);
if (file.fail())
{
return false;
}
// 写CSV 文件头
char bom[2]={0xFF,0xFE};
file.write(bom,2);
WriteCsvFileContent(&file);
// 注意这行别忘了,如果写入的行数为0时(在这里你可以注释掉即文件内容为空),
// 不加这句用EXCEL 打开会出现有乱码的数据显示
// "\r\n" 也相当于文件结束标记(行结束标记)
// By Ben 2014-10-14 11:55:16
file.write((char*)L"\r\n",4);
file.close();
return true;
}
#pragma endregion Write-CsvFile
/
/
#pragma region Read_CsvFile
BOOL DecodeLineString(wstring str, BOOL bWideCharToMultiByte, char **ppData, int &nDataSize)
{
if (str.empty() || ppData == NULL)
{
return FALSE;
}
*ppData = NULL;
int linepos=0;
bool inquotes=false;
int linemax=str.length();
wchar_t c;
int nDstDataSize=linemax+2;
wchar_t* pDstData = new wchar_t[nDstDataSize];
if (pDstData == NULL)
{
return FALSE;
}
ZeroMemory(pDstData,sizeof(wchar_t)*nDstDataSize);
wchar_t szSeparator[5];
ZeroMemory(&szSeparator,sizeof(szSeparator));
int nSepLen;
//GetListSeparator(szSeparator);
//nSepLen = strlen(szSeparator);
//char splitchar=szSeparator[0];
wchar_t szTemp[5];
wstring strSplitW;
if(GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SLIST, szTemp, 5)>0)
{
strSplitW=szTemp;
}
else
{
strSplitW=L",";
}
//wchar_t splitchar=szTemp[0];
wchar_t splitchar=L'\t';
nDataSize=0;
while(str[linepos]!=0 && linepos < linemax)
{
c = str[linepos];
// Fix 43560
if (!inquotes && c==L'"')
{
if(linepos==0)
{
//beginquotechar
inquotes=true;
}
else if(str[linepos-1]==splitchar)
{
//beginquotechar
inquotes=true;
}
else
{
pDstData[nDataSize]=c;
nDataSize++;
}
// End Fix 43560 //The (") and (,) are specified char in the csv file, and the csv parse function is not good when the strings has the specfied chars.
}
else if (inquotes && c==L'"')
{
//quotechar
if ( (linepos+1 <linemax) && (str[linepos+1]==_T('"')) )
{
//encountered 2 double quotes in a row (resolves to 1 double quote)
pDstData[nDataSize]=c;
nDataSize++;
linepos++;
}
else
{
//endquotechar
inquotes=false;
}
}
else if (!inquotes && c==splitchar)
{
//end of field
pDstData[nDataSize]=L'\0';
nDataSize++;
}
else if (!inquotes && (c==L'\r') )
{
}
else if (!inquotes && (c==L'\n') )
{
//record.push_back( curstring );
pDstData[nDataSize]=L'\0';
nDataSize++;
break;
}
else if( c==0xFEFF)
{
}
else
{
//curstring.push_back(c);
pDstData[nDataSize]=c;
nDataSize++;
}
linepos++;
}
*ppData=(char*)pDstData;
nDataSize=(nDataSize+1)*sizeof(wchar_t); // Fix 43163
return TRUE;
}
BOOL DecodeLineString(string str, BOOL bWideCharToMultiByte, char **ppData, int &nDataSize)
{
if (str.empty() || ppData == NULL)
{
return FALSE;
}
*ppData = NULL;
int linepos=0;
bool inquotes=false;
int linemax=str.length();
char c;
int nDstDataSize=linemax+2;
char* pDstData = new char[nDstDataSize];
if (pDstData == NULL)
{
return FALSE;
}
ZeroMemory(pDstData,sizeof(char)*nDstDataSize);
char szSeparator[5];
ZeroMemory(&szSeparator,sizeof(szSeparator));
int nSepLen;
GetListSeparator(szSeparator);
nSepLen = strlen(szSeparator);
char splitchar=szSeparator[0];
nDataSize=0;
while(str[linepos]!=0 && linepos < linemax)
{
c = str[linepos];
// Fix 43560
if (!inquotes && c=='"')
{
if(linepos==0)
{
//beginquotechar
inquotes=true;
}
else if(str[linepos-1]==splitchar)
{
//beginquotechar
inquotes=true;
}
else
{
pDstData[nDataSize]=c;
nDataSize++;
}
// End Fix 43560
}
else if (inquotes && c=='"')
{
//quotechar
if ( (linepos+1 <linemax) && (str[linepos+1]==_T('"')) )
{
//encountered 2 double quotes in a row (resolves to 1 double quote)
pDstData[nDataSize]=c;
nDataSize++;
linepos++;
}
else
{
//endquotechar
inquotes=false;
}
}
else if (!inquotes && c==splitchar)
{
//end of field
pDstData[nDataSize]='\0';
nDataSize++;
}
else if (!inquotes && (c=='\r' || c=='\n') )
{
//record.push_back( curstring );
pDstData[nDataSize]='\0';
nDataSize++;
break;
}
else
{
//curstring.push_back(c);
pDstData[nDataSize]=c;
nDataSize++;
}
linepos++;
}
*ppData=pDstData;
nDataSize=nDataSize+1; // Fix 43163
return TRUE;
}
ifstream& getlineW(ifstream& pStream, wstring& str)
{
wchar_t wch;
str.assign(L"");
while(!pStream.eof())
{
pStream.read((char*)&wch,sizeof(wchar_t));
if(wch==L'\n')
{
break;
}
else if(wch==0xFEFF)
{
continue;
}
str.push_back(wch);
}
return pStream;
}
ifstream& getlineA(ifstream& pStream, string& str)
{
return (ifstream&)getline(pStream,str);
char ch;
str.assign("");
while(!pStream.eof())
{
pStream.read((char*)&ch,sizeof(char));
if(ch=='\n')
{
break;
}
str.push_back(ch);
}
return pStream;
}
// 读取文件文件的第一行
HRESULT ReadCsvFileFirstLine(CString _strDstPath, char **ppData, int &nDataSize, BOOL& bUnicode)
{
*ppData = NULL;
nDataSize = 0;
ifstream file(_strDstPath,ios::binary);
if (file.bad())
{
return E_FAIL;
}
string str;
// Check if it is unicode file
if (!file.eof())
{
// 读取 CSV 文件的BOM (头部两个字节)
char szText[2] = {0};
file.read(szText, 2);
if (!file.fail())
{
bUnicode = (0xFF == (BYTE)szText[0] && 0xFE == (BYTE)szText[1]);
}
if (!bUnicode)
{
// reset file position
file.seekg(0, ios_base::beg);
}
}
#if 1
wstring lineW;
string lineA;
if(bUnicode)
{
while(!file.eof())
{
getlineW(file, lineW);
if (!lineW.empty())
{
if (DecodeLineString(lineW, FALSE, ppData, nDataSize))
{
file.close();
return S_OK;
}
}
}
}
else
{
while(!file.eof())
{
getlineA(file, lineA);
if (!lineA.empty())
{
if (DecodeLineString(lineA, FALSE, ppData, nDataSize))
{
file.close();
return S_OK;
}
}
}
}
#else
while(!file.eof())
{
getline(file, str);
if (!str.empty())
{
if (DecodeLineString(str, FALSE, ppData, nDataSize))
{
file.close();
return S_OK;
}
}
}
#endif
file.close();
return E_FAIL;
}
// 显示CSV 文件的第一行内容
void ShowCsvFirstLine(CString& _strDstPath)
{
BOOL bUnicode = FALSE;
char *pData = NULL;
int nDataSize = 0;
if (S_OK == ReadCsvFileFirstLine(_strDstPath, &pData, nDataSize, bUnicode))
{
int offset = 0;
CString strText;
//#if defined(CM215F) || defined(CM215FW) || defined(FX_M218FW) || defined(FX_M215FW)
#if defined(ABECFG_ENABLE_CJK_INPUT)
WCHAR wszStr[254]={0};
#endif
while (offset < nDataSize)
{
if (bUnicode)
{
strText = (WCHAR*)(pData + offset);
offset += (wcslen((WCHAR*)(pData + offset)) + 1) * sizeof(WCHAR);
}
else
{
//#if defined(CM215F) || defined(CM215FW) || defined(FX_M218FW) || defined(FX_M215FW)
#if defined(ABECFG_ENABLE_CJK_INPUT)
memset(wszStr,00,sizeof(WCHAR)*254);
MultiByteToWideChar(/*932*/CP_UTF8,0,(pData + offset),-1,wszStr,254); // Japanese Codepage
strText=wszStr;
#else
strText = (pData + offset);
#endif
offset += (1 + strlen(pData + offset)) * sizeof(char);
}
wcout << strText.GetString() << " ";
}
wcout << endl << endl << endl;
}
if (pData != NULL)
{
delete []pData;
pData = NULL;
}
}
#pragma endregion Read_CsvFile
//#define WRITE_CSV // 注意:这个定义,在第一次运行时打开,让它生成CSV文件,然后再注释掉看读取的结果
void main()
{
CString strDstPath(_T("d:\\ben.csv"));
#ifdef WRITE_CSV
WriteCsvFile(strDstPath);
#else
ShowCsvFirstLine(strDstPath);
#endif
}
CSV 文件的读写练习
最新推荐文章于 2022-08-10 19:48:57 发布