[TOC]

string <—> CString

string -> CString

C++cpp
std::string str = "string";
CString csRet;
// csRet.Format("%s", str.c_str());
// 如果上句报错就使用
csRet.Format(_T("%s"), str.c_str());

CString -> string

C++cpp
CString cstr("string");
std::string str;
 
#ifdef _UNICODE
// 工程为 Unicode 时,CString 实际是 CStringW,需要宽转窄
int nLen = WideCharToMultiByte(CP_ACP, 0, cstr, cstr.GetLength(), NULL, 0, NULL, NULL);
char* pBuf = new char[nLen + 1];
WideCharToMultiByte(CP_ACP, 0, cstr, cstr.GetLength(), pBuf, nLen, NULL, NULL);
pBuf[nLen] = '\0';
str = pBuf;
delete[] pBuf;
#else
// 工程为 ANSI/MBCS 时,CString 实际是 CStringA,可直接转换
str = cstr.GetBuffer(0);
#endif

简洁写法(Unicode 工程):std::string str = CW2A(cstr);(需包含 <atlconv.h>,或使用 ATL 的 CT2A)。

string < — > char*

string -> const char*

C++cpp
std::string str = "hello";
const char* p = str.c_str();   // 只读,不保证以 '\0' 结尾(C++11 起保证)
const char* d = str.data();    // 同 c_str

char* -> string

C++cpp
const char* p = "hello";
std::string str(p);            // 以 '\0' 结尾的 C 字符串
std::string str2(p, len);      // 指定长度(可含 '\0')

wstring < — > CString

wstring -> CString

C++cpp
std::wstring ws = L"宽字符串";
CString cstr(ws.c_str());   // CStringW 可直接用 wchar_t* 构造

CString -> wstring

C++cpp
CString cstr(_T("宽字符串"));
std::wstring ws(cstr.GetString());   // Unicode 工程下直接转换

string < — > wstring

string -> wstring

solution 1(标准库,注意 std::wstring_convert 与 std::codecvt_utf8 在 C++17 起被弃用,仅适用于 C++11/14;若需 C++17+ 仍想用,需在 CMake/MSVC 中链接 legacy_stdlib 相关定义,生产环境建议改用 Win32 API 方案):

C++cpp
#include <string>
#include <locale>
#include <codecvt>
 
//convert string to wstring
inline std::wstring to_wide_string(const std::string& input)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    return converter.from_bytes(input);
}

solution 2(Win32 API,推荐,与 wstring -> string 思路对称):

C++cpp
// UTF-8 string -> wstring
inline std::wstring stringToWstring_utf8(const std::string& str)
{
    if (str.empty()) return std::wstring();
 
    int nLen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), NULL, 0);
    if (nLen == 0) return std::wstring();
 
    std::wstring result(nLen, L'\0');
    MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), &result[0], nLen);
    return result;
}
 
// ANSI / 本地代码页 string -> wstring
inline std::wstring stringToWstring_ansi(const std::string& str)
{
    if (str.empty()) return std::wstring();
 
    int nLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), (int)str.size(), NULL, 0);
    if (nLen == 0) return std::wstring();
 
    std::wstring result(nLen, L'\0');
    MultiByteToWideChar(CP_ACP, 0, str.c_str(), (int)str.size(), &result[0], nLen);
    return result;
}

老写法(保留):兼容 ANSI 字符串的 MultiByteToWideChar + 手动 TCHAR* buffer 方案(与下面 wstring -> string 旧版一致),仍然有效但不如直接用 std::wstring 构造方便。

wstring -> string

solution 1(标准库,注意 std::wstring_convert 与 std::codecvt_utf8 在 C++17 起被弃用,仅适用于 C++11/14):

C++cpp
#include <string>
#include <locale>
#include <codecvt>
 
// convert wstring to string
inline std::string to_byte_string(const std::wstring& input)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    return converter.to_bytes(input);
}

solution 2(Win32 API 通用方案,推荐——std::wstring_convert 跨平台但不安全、易 deprecated):

C++cpp
// 宽字符 -> 多字节(ANSI / 本地代码页),可处理任意 wstring
inline std::string wstringToString_ansi(const std::wstring& wstr)
{
    if (wstr.empty()) return std::string();
 
    // 1) 先询问需要多少字节(不包含结尾 '\0')
    int nLen = WideCharToMultiByte(
        CP_ACP,            // ANSI / 本地代码页
        0,
        wstr.c_str(),
        (int)wstr.size(),
        NULL, 0,
        NULL, NULL);
    if (nLen == 0) return std::string();
 
    // 2) 分配缓冲区并真正转换
    std::string result(nLen, '\0');
    WideCharToMultiByte(
        CP_ACP, 0,
        wstr.c_str(), (int)wstr.size(),
        &result[0], nLen,
        NULL, NULL);
    return result;
}
 
// 宽字符 -> UTF-8(跨平台/跨区域推荐)
inline std::string wstringToString_utf8(const std::wstring& wstr)
{
    if (wstr.empty()) return std::string();
 
    int nLen = WideCharToMultiByte(
        CP_UTF8, 0,
        wstr.c_str(), (int)wstr.size(),
        NULL, 0, NULL, NULL);
    if (nLen == 0) return std::string();
 
    std::string result(nLen, '\0');
    WideCharToMultiByte(
        CP_UTF8, 0,
        wstr.c_str(), (int)wstr.size(),
        &result[0], nLen, NULL, NULL);
    return result;
}

solution 3(MFC 风格,与 CString -> string 里的写法对称):

C++cpp
CString cstr(L"宽字符串");
int nLen = WideCharToMultiByte(CP_ACP, 0, cstr, cstr.GetLength(), NULL, 0, NULL, NULL);
char* pBuf = new char[nLen + 1];
WideCharToMultiByte(CP_ACP, 0, cstr, cstr.GetLength(), pBuf, nLen, NULL, NULL);
pBuf[nLen] = '\0';
std::string str(pBuf);
delete[] pBuf;

选哪个?

  • 跨平台 / 与外部系统(HTTP、文件、日志)交换 → wstringToString_utf8
  • Windows 内部使用、注册表、MBCS API → wstringToString_ansi
  • 在 Unicode 工程里写 CStringW 互转 → solution 3 或 CW2A(cstr) 宏(<atlconv.h>)

DWORD <---> string

C++cpp
string DwordToString(DWORD val)
{
	string cur_str = to_string(long long (val));
	return cur_str;
}
C++cpp
DWORD StringToDword(string val)
{
	DWORD cur_dword;
	sscanf(val.c_str(),"%ul",&cur_dword);
	return cur_dword;
}

更多查看已实现的编码转换文件:

win_str_utils

win_str_utils.md