VS2013 默認 Unicode 字符集,CString 為 wchar_t。直接用 CStdioFile::WriteString 或流操作符寫入 CSV,若文件流未設置正確 locale,中文會按當前代碼頁 (CP936/GBK) 寫入,導致 Excel 打開亂碼或存儲為 UTF-16 無法識別。
// 保存原 locale
char* old_locale = _strdup(setlocale(LC_CTYPE, NULL));
// 設置為中文簡體 (CP936)
setlocale(LC_CTYPE, "chs"); // 或 "zh_CN.GBK", ".936"
// 執行文件寫入操作
CStdioFile file;
file.Open(_T("data.csv"), CFile::modeCreate | CFile::modeWrite | CFile::typeText);
file.WriteString(_T("姓名,年齡\n"));
file.WriteString(_T("張三,25\n"));
file.Close();
// 恢復 locale
setlocale(LC_CTYPE, old_locale);
free(old_locale);
setlocale(LC_CTYPE, "chs") 將 C 運行庫的字符轉換設置為 GBK (代碼頁 936)。CStdioFile::WriteString 內部調用 fwrite,會將 wchar_t 按當前 locale 轉為多字節寫入。file.Open(_T("data.csv"), CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
// 寫入 UTF-8 BOM
BYTE bom[] = {0xEF, 0xBB, 0xBF};
file.Write(bom, 3);
// 手寫 UTF-8 編碼轉換
CStringA utf8 = CW2A(str, CP_UTF8);
file.WriteString(utf8);
優點:跨平台通用,支援所有語言。缺點:需手動轉碼,Excel 2016+ 才完美支援無 BOM UTF-8。
setlocale("chs") + GBK 最省事。CArchive 寫文本,CArchive 為二進制序列化。