在 Shift-JIS 中写入 CSV 文件(MFC VC++,Windows Embedded - WinCE)
Write a CSV file in Shift-JIS (MFC VC++, Windows Embedded - WinCE)
正如标题所说,我一直在尝试将用户输入CEdit控件的数据写入文件。
系统是手持终端运行WindowsCE,我的测试应用是运行,我尝试输入测试数据(日文罗马字、平假名、片假名和汉字与正常的英文字母数字数据混合在一起)最初显示在 CListCtrl 中。在我的测试应用UI中,字符在手持显示屏上显示正常。
最后,我尝试从 List 控件中读回数据并将其写入文本 CSV 文件。我从控件中读回的数据是正确的,但在将其写入 CSV 时,事情变得一团糟,我的 CSV 文件不可读,并显示奇怪的符号和无意义的字母数字垃圾。
我对此进行了搜索,最后在 Whosebug 上找到了一个类似的问题:
UTF-8, CString and CFile? (C++, MFC)
我尝试了他们的一些建议,最终得到了一个正确的 UTF-8 CSV 文件。
write-to-csv-file 代码如下:
CStdioFile cCsvFile = CStdioFile();
cCsvFile.Open(cFileName, CFile::modeCreate|CFile::modeWrite);
char BOM[3]={0xEF, 0xBB, 0xBF}; // Utf-8 BOM
cCsvFile.Write(BOM,3); // Write the BOM first
for(int i = 0; i < M_cDataList.GetItemCount(); i++)
{
CString cDataStr = _T("\"") + M_cDataList.GetItemText(i, 0) + _T("\",");
cDataStr += _T("\"") + M_cDataList.GetItemText(i, 1) + _T("\",");
cDataStr += _T("\"") + M_cDataList.GetItemText(i, 2) + _T("\"\r\n");
CT2CA outputString(cDataStr, CP_UTF8);
cCsvFile.Write(outputString, ::strlen(outputString));
}
cCsvFile.Close();
目前一切正常。
现在,对于我的用例,我想稍微改变一下,将 CSV 文件编码为 Shift-JIS,而不是 UTF-8。
对于Shift-JIS,我使用什么BOM,我应该对上面的代码做哪些修改?
感谢您的任何建议和帮助。
Shift-JIS 的代码页显然是 932。使用 WideCharToMultiByte
和 MultiByteToWideChar
进行转换。例如:
CStringW source = L"日本語ABC平仮名ABCひらがなABC片仮名ABCカタカナABC漢字ABC①";
CStringA destination = CW2A(source, 932);
CStringW convertBack = CA2W(destination, 932);
//Testing:
ASSERT(source == convertBack);
AfxMessageBox(convertBack);
据我所知,Shift-JIS 没有 BOM。 Perhaps 你只想使用 UTF16。例如:
CStdioFile file;
file.Open(L"utf16.txt", CFile::modeCreate | CFile::modeWrite| CFile::typeUnicode);
BYTE bom[2] = { 0xFF, 0xFE };
file.Write(bom, 2);
CString str = L"日本語";
file.WriteString(str);
file.Close();
ps,根据这个 page 代码页 932 和 Shift-JIS 之间存在一些问题,尽管我无法复制任何错误。
正如标题所说,我一直在尝试将用户输入CEdit控件的数据写入文件。
系统是手持终端运行WindowsCE,我的测试应用是运行,我尝试输入测试数据(日文罗马字、平假名、片假名和汉字与正常的英文字母数字数据混合在一起)最初显示在 CListCtrl 中。在我的测试应用UI中,字符在手持显示屏上显示正常。 最后,我尝试从 List 控件中读回数据并将其写入文本 CSV 文件。我从控件中读回的数据是正确的,但在将其写入 CSV 时,事情变得一团糟,我的 CSV 文件不可读,并显示奇怪的符号和无意义的字母数字垃圾。
我对此进行了搜索,最后在 Whosebug 上找到了一个类似的问题: UTF-8, CString and CFile? (C++, MFC)
我尝试了他们的一些建议,最终得到了一个正确的 UTF-8 CSV 文件。
write-to-csv-file 代码如下:
CStdioFile cCsvFile = CStdioFile();
cCsvFile.Open(cFileName, CFile::modeCreate|CFile::modeWrite);
char BOM[3]={0xEF, 0xBB, 0xBF}; // Utf-8 BOM
cCsvFile.Write(BOM,3); // Write the BOM first
for(int i = 0; i < M_cDataList.GetItemCount(); i++)
{
CString cDataStr = _T("\"") + M_cDataList.GetItemText(i, 0) + _T("\",");
cDataStr += _T("\"") + M_cDataList.GetItemText(i, 1) + _T("\",");
cDataStr += _T("\"") + M_cDataList.GetItemText(i, 2) + _T("\"\r\n");
CT2CA outputString(cDataStr, CP_UTF8);
cCsvFile.Write(outputString, ::strlen(outputString));
}
cCsvFile.Close();
目前一切正常。 现在,对于我的用例,我想稍微改变一下,将 CSV 文件编码为 Shift-JIS,而不是 UTF-8。 对于Shift-JIS,我使用什么BOM,我应该对上面的代码做哪些修改?
感谢您的任何建议和帮助。
Shift-JIS 的代码页显然是 932。使用 WideCharToMultiByte
和 MultiByteToWideChar
进行转换。例如:
CStringW source = L"日本語ABC平仮名ABCひらがなABC片仮名ABCカタカナABC漢字ABC①";
CStringA destination = CW2A(source, 932);
CStringW convertBack = CA2W(destination, 932);
//Testing:
ASSERT(source == convertBack);
AfxMessageBox(convertBack);
据我所知,Shift-JIS 没有 BOM。 Perhaps 你只想使用 UTF16。例如:
CStdioFile file;
file.Open(L"utf16.txt", CFile::modeCreate | CFile::modeWrite| CFile::typeUnicode);
BYTE bom[2] = { 0xFF, 0xFE };
file.Write(bom, 2);
CString str = L"日本語";
file.WriteString(str);
file.Close();
ps,根据这个 page 代码页 932 和 Shift-JIS 之间存在一些问题,尽管我无法复制任何错误。