Unicode 编码(UTF-16)和多字节编码(如 GBK) 环境下,wstring、string、wchar_t*、char* 和 CString 之间的互转方法总

1. 核心概念

术语Unicode 工程(UTF-16)多字节工程(本地代码页,如 GBK)
TCHAR定义为 wchar_t定义为 char
CString实际为 CStringW(基于 wchar_t实际为 CStringA(基于 char
API 调用调用 XXXW(如 MessageBoxW调用 XXXA(如 MessageBoxA

2. 互转方法

2.1 std::wstring ↔ wchar_t*

Unicode 和多字节工程均适用
// wstring → wchar_t*
std::wstring wstr = L"中文";
const wchar_t* wptr1 = wstr.c_str();  // 只读指针

wchar_t* wptr2 = new wchar_t[wstr.size() + 1];
wcscpy_s(wptr2, wstr.size() + 1, wstr.c_str()); // 可修改拷贝
// 使用后需 delete[] wptr2;

// wchar_t* → wstring
const wchar_t* wptr = L"中文";
std::wstring wstr(wptr); // 直接构造

2.2 std::string ↔ char*

Unicode 和多字节工程均适用
// string → char*
std::string str = "Hello";
const char* cptr1 = str.c_str();  // 只读指针

char* cptr2 = new char[str.size() + 1];
strcpy_s(cptr2, str.size() + 1, str.c_str()); // 可修改拷贝
// 使用后需 delete[] cptr2;

// char* → string
const char* cptr = "Hello";
std::string str(cptr); // 直接构造

2.3 std::wstring ↔ CString

Unicode 工程(CString = CStringW
// wstring → CString
std::wstring wstr = L"中文";
CString cstr1(wstr.c_str());  // 直接构造
CString cstr2 = wstr.c_str(); // 赋值

// CString → wstring
CString cstr = L"中文";
std::wstring wstr1(cstr.GetString()); // 推荐方式
std::wstring wstr2((LPCTSTR)cstr);    // 旧写法(兼容早期 MFC)
多字节工程(CString = CStringA
// wstring → CString(需转码)
std::wstring wstr = L"中文";
CString cstr = CW2A(wstr.c_str(), CP_ACP); // 转为本地代码页(如 GBK)

// CString → wstring(需转码)
CString cstr = "中文";
std::wstring wstr = CA2W(cstr.GetString(), CP_ACP); // 转为 UTF-16

2.4 std::string ↔ CString

Unicode 工程(CString = CStringW
// string → CString(需转码)
std::string str = "中文";
CString cstr = CA2W(str.c_str(), CP_UTF8); // 假设 str 是 UTF-8

// CString → string(需转码)
CString cstr = L"中文";
std::string str = CW2A(cstr.GetString(), CP_UTF8); // 转为 UTF-8
多字节工程(CString = CStringA
// string → CString(直接转换,需确保编码一致)
std::string str = "中文"; // 假设是 GBK
CString cstr(str.c_str());

// CString → string
CString cstr = "中文";
std::string str((LPCTSTR)cstr); // 直接转换(需确保编码一致)

2.5 CString ↔ wchar_t*

Unicode 工程(CString = CStringW
// CString → wchar_t*
CString cstr = L"中文";
const wchar_t* wptr1 = cstr.GetString(); // 只读指针

wchar_t* wptr2 = new wchar_t[cstr.GetLength() + 1];
wcscpy_s(wptr2, cstr.GetLength() + 1, cstr.GetString()); // 可修改拷贝
// 使用后需 delete[] wptr2;

// wchar_t* → CString
const wchar_t* wptr = L"中文";
CString cstr(wptr); // 直接构造
多字节工程(CString = CStringA
// CString → wchar_t*(需转码)
CString cstr = "中文";
std::wstring wstr = CA2W(cstr.GetString(), CP_ACP); // 转为 UTF-16
const wchar_t* wptr = wstr.c_str();

// wchar_t* → CString(需转码)
const wchar_t* wptr = L"中文";
CString cstr = CW2A(wptr, CP_ACP); // 转为本地代码页(如 GBK)

2.6 CString ↔ std::string

Unicode 工程(CString = CStringW
// CString → string(UTF-8)
CString cstr = L"中文";
std::string str = CW2A(cstr.GetString(), CP_UTF8); // 转为 UTF-8

// string → CString(UTF-8)
std::string str = u8"中文";
CString cstr = CA2W(str.c_str(), CP_UTF8); // 转为 UTF-16
多字节工程(CString = CStringA
// CString → string(直接转换,需确保编码一致)
CString cstr = "中文"; // 假设是 GBK
std::string str((LPCTSTR)cstr);

// string → CString(直接转换,需确保编码一致)
std::string str = "中文"; // 假设是 GBK
CString cstr(str.c_str());

3. 关键注意事项

  1. 编码一致性

    • 在 Unicode 工程 中,CString 是 wchar_t 类型,std::string 需明确编码(如 UTF-8)。

    • 在 多字节工程 中,CString 是 char 类型,需确保与 std::string 编码一致(如 GBK)。

  2. 转码工具

    • CA2W 和 CW2A 是 ATL 提供的宏,用于编码转换(需包含 <atlconv.h>)。

    • 若未使用 ATL,可用 WideCharToMultiByte 和 MultiByteToWideChar 替代。

  3. 内存管理

    • 使用 new 分配的内存需手动 delete[]

    • CString 和 std::string/std::wstring 自动管理内存。

  4. 跨工程兼容性

    • 若代码需在 Unicode 和 多字节 工程间移植,建议使用 TCHAR 和 _T() 宏。

4. 完整示例代码

#include <string>
#include <atlstr.h> // CString
#include <atlconv.h> // CA2W, CW2A

int main() {
    // Unicode 工程示例
    #ifdef _UNICODE
    std::wstring wstr = L"中文";
    CString cstr = wstr.c_str(); // wstring → CString
    std::wstring wstr2 = cstr.GetString(); // CString → wstring

    std::string str = u8"Hello";
    CString cstr2 = CA2W(str.c_str(), CP_UTF8); // string → CString (UTF-8 → UTF-16)
    std::string str2 = CW2A(cstr2.GetString(), CP_UTF8); // CString → string (UTF-16 → UTF-8)
    #else
    // 多字节工程示例
    std::string str = "中文"; // GBK
    CString cstr(str.c_str()); // string → CString
    std::string str2 = (LPCTSTR)cstr; // CString → string

    std::wstring wstr = CA2W(str.c_str(), CP_ACP); // string → wstring (GBK → UTF-16)
    CString cstr2 = CW2A(wstr.c_str(), CP_ACP); // wstring → CString (UTF-16 → GBK)
    #endif

    return 0;
}

5. 总结

转换方向Unicode 工程多字节工程
wstring ↔ wchar_t*直接转换(c_str()直接转换(c_str()
string ↔ char*直接转换(c_str()直接转换(c_str()
wstring ↔ CString直接转换(CString(wstr.c_str())需转码(CA2W / CW2A
string ↔ CString需转码(CA2W / CW2A,UTF-8 ↔ UTF-16)直接转换(需确保编码一致)
CString ↔ wchar_t*直接转换(GetString()需转码(CA2W / CW2A
CString ↔ string需转码(CW2A,UTF-16 → UTF-8)直接转换(需确保编码一致)

根据工程字符集设置选择合适方法,并始终注意 编码一致性 和 内存管理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值