首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

MFC URL 編碼實現:GB2312 轉 UTF-8 後百分號編碼,解決中文參數傳遞亂碼

     編輯:程式設計疑難解答

問題背景

MFC 多字節字符集項目中,URL 參數包含中文直接拼接會導致服務端接收亂碼。標準做法:中文 → UTF-8 字節流 → 每字節 %XX 編碼。

完整實現代碼

// 工具函數:Unicode(WCHAR) → UTF-8 (3字節)
void UnicodeToUTF_8(char* pOut, WCHAR* pText) {
    // WCHAR 低字節在前(小端序)
    char* pchar = (char*)pText;
    pOut[0] = 0xE0 | ((pchar[1] & 0xF0) >> 4);
    pOut[1] = 0x80 | ((pchar[1] & 0x0F) << 2) | ((pchar[0] & 0xC0) >> 6);
    pOut[2] = 0x80 | (pchar[0] & 0x3F);
}

// GB2312 字符串 → UTF-8 編碼的 CString
void GB2312ToUTF_8(CString& pOut, char* pText, int pLen) {
    char buf[4] = {0};
    pOut.Empty();
    for (int i = 0; i < pLen; ) {
        if ((BYTE)pText[i] >= 0) { // ASCII 直接複製
            pOut.AppendChar(pText[i++]);
        } else { // 雙字節漢字
            WCHAR wc;
            ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pText + i, 2, &wc, 1);
            UnicodeToUTF_8(buf, &wc);
            pOut.Append(buf, 3);
            i += 2;
        }
    }
}

// 終極 URL 編碼函數
CString UrlUTF8(char* str) {
    CString utf8, result;
    GB2312ToUTF_8(utf8, str, (int)strlen(str));
    
    for (int i = 0; i < utf8.GetLength(); i++) {
        BYTE ch = (BYTE)utf8.GetAt(i);
        if (isalnum(ch) || ch == '-' || ch == '_' || ch == '.' || ch == '~') {
            result.AppendChar((char)ch); // RFC 3986 保留字符不編碼
        } else if (ch == ' ') {
            result.AppendChar('+'); // 表單空格編碼為 +
        } else {
            char hex[4];
            sprintf_s(hex, "%%%02X", ch); // 大寫十六進制
            result.Append(hex);
        }
    }
    return result;
}

使用示例

CString param = "用戶名=張三&城市=北京";
CString encoded = UrlUTF8(param.GetBuffer());
param.ReleaseBuffer();
// encoded: "%E7%94%A8%E6%88%B7%E5%90%8D=%E5%BC%A0%E4%B8%89&%E5%9F%8E%E5%B8%82=%E5%8C%97%E4%BA%AC"

關鍵點說明

  1. 雙重轉換:項目為 MBCS (GB2312) → 先 MultiByteToWideChar 轉 Unicode → 再手寫 Unicode→UTF-8(避免依賴 C++11 codecvt)。
  2. RFC 3986 合規:字母數字及 -_.~ 不編碼;空格編為 +(application/x-www-form-urlencoded 標準);其餘 %XX 大寫。
  3. 編碼一致性:服務端解碼必須同為 UTF-8,否則仍會亂碼。

現代替代方案

若項目升級至 Unicode 字符集 (VS 默認),可直接使用 CStringA 配合 WideCharToMultiByte(CP_UTF8) 簡化流程,或引入 cpp-httplib、restc-cpp 等現代網絡庫自動處理編碼。

總結

MFC 多字節項目實現 URL 編碼核心路徑:GB2312 → Unicode → UTF-8 → %XX。上述代碼經實戰驗證,可直接集成。長期建議遷移至 Unicode 字符集並使用成熟網絡庫,減少手工編碼維護成本。

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