首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 寬窄字串轉換:std::wstring 與 std::string 互轉完整實作

     編輯:VC 教學

前言

Windows API 多使用 Unicode(wchar_t*),而標準庫、網路協定、第三方庫常用 ANSI/UTF-8(char*)。專案中頻繁需要在 std::wstring 與 std::string 之間轉換。本文提供兩個健全的轉換函式,支援指定地區設定(Code Page 936 簡體中文)。

核心轉換函式

窄字串 → 寬字串


#include <string>
#include <clocale>
#include <cstdlib>

std::wstring ToWideString(const char* pszStr, int len = -1)
{
    if (!pszStr) return L"";
    if (len < 0) len = (int)strlen(pszStr);

    // 設定地區為中文代碼頁 936 (GBK)
    std::setlocale(LC_ALL, ".936");

    int wlen = MultiByteToWideChar(CP_ACP, 0, pszStr, len, NULL, 0);
    if (wlen <= 0) return L"";

    std::wstring wstr(wlen, L'\0');
    MultiByteToWideChar(CP_ACP, 0, pszStr, len, &wstr[0], wlen);

    std::setlocale(LC_ALL, "C"); // 還原
    return wstr;
}

寬字串 → 窄字串


std::string ToNarrowString(const wchar_t* pwzStr, int len = -1)
{
    if (!pwzStr) return "";
    if (len < 0) len = (int)wcslen(pwzStr);

    std::setlocale(LC_ALL, ".936");

    int nlen = WideCharToMultiByte(CP_ACP, 0, pwzStr, len, NULL, 0, NULL, NULL);
    if (nlen <= 0) return "";

    std::string str(nlen, '\0');
    WideCharToMultiByte(CP_ACP, 0, pwzStr, len, &str[0], nlen, NULL, NULL);

    std::setlocale(LC_ALL, "C");
    return str;
}

使用範例


std::string ansi = "中文測試";
std::wstring wide = ToWideString(ansi.c_str());
// wide == L"中文測試"

std::string back = ToNarrowString(wide.c_str());
// back == "中文測試"

進階:支援 UTF-8 編碼

若專案統一使用 UTF-8,請將 CP_ACP 改為 CP_UTF8,並移除 setlocale 呼叫:


std::wstring Utf8ToWide(const std::string& utf8) {
    int wlen = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, NULL, 0);
    std::wstring w(wlen, L'\0');
    MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, &w[0], wlen);
    return w;
}

std::string WideToUtf8(const std::wstring& wide) {
    int nlen = WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), -1, NULL, 0, NULL, NULL);
    std::string s(nlen, '\0');
    WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), -1, &s[0], nlen, NULL, NULL);
    return s;
}

MFC CString 專用轉換


// ANSI/MBCS 專案
CStringA ansi = "測試";
CStringW wide = ansi; // 隱含轉換 (需 _UNICODE 未定義)

// Unicode 專案
CStringW wide = L"測試";
CStringA ansi = wide; // 隱含轉換

// 手動控制 (ATL 轉換巨集)
USES_CONVERSION;
LPCWSTR w = A2W(ansi);
LPCSTR a = W2A(wide);

常見陷阱

  • setlocale 非執行緒安全;多執行緒環境請改用 MultiByteToWideChar/WideCharToMultiByte 直接指定 CP_ACP 或 CP_UTF8,不要呼叫 setlocale。
  • 緩衝區大小計算:先傳 NULL 取得所需長度,再配置記憶體。
  • 原始碼檔案編碼:儲存為 UTF-8 with BOM 或 Unicode,避免字串常值編碼不一致。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved