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

Windows API 實現 Big5/GB2312 雙向編碼轉換完全指南

     編輯:VC++

核心思路:Unicode 作為中介

Windows 系統內核基於 Unicode (UTF-16)。利用系統 API 實現編碼轉換的標準路徑為:

  1. 源編碼 (Multi-byte) → MultiByteToWideChar → Unicode (Wide-char)
  2. Unicode → WideCharToMultiByte → 目標編碼 (Multi-byte)
  3. 簡繁體轉換:LCMapString 配合 LCMAP_SIMPLIFIED_CHINESE / LCMAP_TRADITIONAL_CHINESE

代碼頁標識對照表

編碼代碼頁常用名稱
Big5 (繁體中文)950CP950
GB2312/GBK (簡體中文)936CP936
Unicode (系統默認)1200 (UTF-16LE)WideChar

功能一:Big5 轉 GB2312 簡體 (Big2Gb)

AnsiString __fastcall Big2Gb(AnsiString sBig) {
    // 1. Big5 → Unicode
    char* pszBig5 = sBig.c_str();
    int iLen = MultiByteToWideChar(950, 0, pszBig5, -1, NULL, 0);
    wchar_t* wszUnicode = new wchar_t[iLen + 1];
    MultiByteToWideChar(950, 0, pszBig5, -1, wszUnicode, iLen);

    // 2. Unicode → GBK 繁體 (中介)
    iLen = WideCharToMultiByte(936, 0, wszUnicode, -1, NULL, 0, NULL, NULL);
    char* pszGbTrad = new char[iLen + 1];
    WideCharToMultiByte(936, 0, wszUnicode, -1, pszGbTrad, iLen, NULL, NULL);

    // 3. GBK 繁體 → GBK 簡體 (核心步驟)
    char* pszGbSimp = new char[iLen + 1];
    LCMapString(0x0804, LCMAP_SIMPLIFIED_CHINESE, pszGbTrad, -1, pszGbSimp, iLen);

    // 4. 清理與返回
    AnsiString sGb = pszGbSimp;
    delete[] wszUnicode;
    delete[] pszGbTrad;
    delete[] pszGbSimp;
    return sGb;
}

功能二:GB2312 轉 Big5 繁體 (Gb2Big)

AnsiString __fastcall Gb2Big(AnsiString sGb) {
    // 1. GBK 簡體 → GBK 繁體
    char* pszGbSimp = sGb.c_str();
    int iLen = MultiByteToWideChar(936, 0, pszGbSimp, -1, NULL, 0);
    char* pszGbTrad = new char[iLen * 2 + 1]; // 預留擴展空間
    LCMapString(0x0804, LCMAP_TRADITIONAL_CHINESE, pszGbSimp, -1, pszGbTrad, iLen * 2);

    // 2. GBK 繁體 → Unicode
    wchar_t* wszUnicode = new wchar_t[iLen + 1];
    MultiByteToWideChar(936, 0, pszGbTrad, -1, wszUnicode, iLen);

    // 3. Unicode → Big5
    iLen = WideCharToMultiByte(950, 0, wszUnicode, -1, NULL, 0, NULL, NULL);
    char* pszBig5 = new char[iLen + 1];
    WideCharToMultiByte(950, 0, wszUnicode, -1, pszBig5, iLen, NULL, NULL);

    // 4. 清理與返回
    AnsiString sBig5 = pszBig5;
    delete[] wszUnicode;
    delete[] pszGbTrad;
    delete[] pszBig5;
    return sBig5;
}

關鍵技術細節解析

1. 兩次轉換緩衝區大小查詢模式

所有 MultiByteToWideChar 和 WideCharToMultiByte 首次調用傳 NULL 緩衝區以獲取所需字符數,再分配內存二次調用實際轉換。這是 Windows API 標準用法,避免緩衝區溢出。

2. LCMapString 實現簡繁轉換

  • LCMAP_SIMPLIFIED_CHINESE (0x02000000):繁轉簡
  • LCMAP_TRADITIONAL_CHINESE (0x04000000):簡轉繁
  • Locale ID 0x0804 代表中文 (中華人民共和國),此處作為標準簡體中文環境標識使用

注意: LCMapString 基於字符映射表,對於「一簡對多繁」或異體字可能無法完美覆蓋,生產環境建議引入專業詞庫庫 (如 OpenCC)。

3. 內存管理規範

  • 使用 new[] 分配,delete[] 釋放,嚴格配對
  • 異常安全:建議封裝為 RAII 智能指針或 std::vector/wstring 自動管理

現代 C++ 封裝建議 (跨平台/無 MFC/ATL 依賴)

#include 
#include 
#include 
#include 

std::string ConvertEncoding(const std::string& src, UINT srcCP, UINT dstCP) {
    if (src.empty()) return "";
    // Src CP -> UTF-16
    int wlen = MultiByteToWideChar(srcCP, 0, src.c_str(), -1, nullptr, 0);
    std::vector wbuf(wlen);
    MultiByteToWideChar(srcCP, 0, src.c_str(), -1, wbuf.data(), wlen);
    // UTF-16 -> Dst CP
    int dlen = WideCharToMultiByte(dstCP, 0, wbuf.data(), -1, nullptr, 0, nullptr, nullptr);
    std::string dst(dlen, '\0');
    WideCharToMultiByte(dstCP, 0, wbuf.data(), -1, &dst[0], dlen, nullptr, nullptr);
    if (!dst.empty() && dst.back() == '\0') dst.pop_back(); // 移除結尾空字符
    return dst;
}

std::string Big5ToGbSimp(const std::string& big5) {
    // Big5 -> GBK Trad
    std::string gbkTrad = ConvertEncoding(big5, 950, 936);
    // GBK Trad -> GBK Simp (LCMapString 需要寬字符)
    int wlen = MultiByteToWideChar(936, 0, gbkTrad.c_str(), -1, nullptr, 0);
    std::vector wbuf(wlen);
    MultiByteToWideChar(936, 0, gbkTrad.c_str(), -1, wbuf.data(), wlen);
    std::vector wout(wlen * 2);
    LCMapString(0x0804, LCMAP_SIMPLIFIED_CHINESE, wbuf.data(), -1, wout.data(), wout.size());
    // GBK Simp (Wide) -> GBK Simp (Multi-byte)
    return ConvertEncoding(std::wstring(wout.data()), 936, 936); // 復用轉換邏輯需微調,此處略
}

總結

利用 Windows 核心 API (MultiByteToWideChar, WideCharToMultiByte, LCMapString) 實現 Big5/GB2312 雙向轉換,無需第三方庫,兼容性極佳。掌握「多位元組 ↔ Unicode ↔ 多位元組」及「LCMapString 簡繁映射」兩大核心模式,即可輕鬆應對中文編碼互轉需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved