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

C/C++ 中 sprintf 与 swprintf 的字符集轉換用法詳解

     編輯:關於C

前言

Windows 開發中常需在 ANSI(多字節)字符串與 Unicode(寬字符)字符串之間轉換。`sprintf` 系列處理 ANSI,`swprintf` 系列處理 Unicode。關鍵在於格式字符串與參數的字符集匹配,以及大小寫格式符號的含義差異。

核心規則速查表

函數格式串類型目標緩衝區%s 含義%S 含義
sprintfANSI (char*)ANSI (char*)ANSI 字符串Unicode → ANSI 轉換
swprintfUnicode (wchar_t*)Unicode (wchar_t*)ANSI → Unicode 轉換Unicode 字符串

記憶口訣:sprintf 看著小寫 `s` → `%s` 接 ANSI,`%S` 接寬字符(轉換);swprintf 看著大寫 `S`(wide) → `%S` 接寬字符,`%s` 接 ANSI(轉換)。

代碼示例


#include 
#include 

int main() {
    char  szA[100];      // ANSI 緩衝區
    WCHAR szW[100];      // Unicode 緩衝區

    // 1. 純 ANSI 環境
    sprintf(szA, "%s", "ANSI Str");
    printf("ANSI: %s\n", szA);

    // 2. Unicode 轉 ANSI (sprintf + %S)
    sprintf(szA, "%S", L"Unicode Str");
    printf("Wide->ANSI: %s\n", szA);

    // 3. 純 Unicode 環境
    swprintf(szW, L"%s", L"Unicode Str");
    wprintf(L"Wide: %s\n", szW);

    // 4. ANSI 轉 Unicode (swprintf + %s)
    swprintf(szW, L"%S", "ANSI Str");
    wprintf(L"ANSI->Wide: %s\n", szW);

    return 0;
}

底層原理

  • sprintf 內部調用 `vsprintf`,最終調用 `WideCharToMultiByte`(當遇到 `%S` 時)將 `wchar_t*` 按當前代碼頁(CP_ACP)轉為 `char*`。
  • swprintf 內部調用 `vswprintf`,遇到 `%s` 時調用 `MultiByteToWideChar` 將 `char*` 轉為 `wchar_t*`。
  • 轉換使用進程默認 ANSI 代碼頁(通常為 GBK/CP936 中文環境),跨代碼頁場景建議顯式調用 `WideCharToMultiByte`/`MultiByteToWideChar` 指定 `CP_UTF8`。

安全增強版

現代代碼應使用帶 `_s` 後綴的安全版本,防止緩衝區溢出:


// C11 / VS 安全版
sprintf_s(szA, sizeof(szA), "%S", L"Unicode Str");
swprintf_s(szW, _countof(szW), L"%S", "ANSI Str");

常見錯誤與避坑

  1. 格式字符串字符集不匹配:`sprintf(szA, L"%s", ...)` 編譯警告/錯誤,格式串必須與函數字符集一致。
  2. %s/%S 大小寫搞反:導致亂碼或崩潰。
  3. 緩衝區大小不足:Unicode 字符轉 ANSI 可能縮短(雙字節→單字節),但 ANSI 轉 Unicode 會加長(單字節→雙字節),需預留足夠空間(`wcslen * 2 + 1`)。
  4. 嵌入式/無 CRT 環境:標準庫可能不支持 `%S` 轉換,需自行實現或用 `iconv`/`ICU`。

總結

掌握 `sprintf`/`swprintf` 的 `%s`、`%S` 語義,是 Windows 雙字符集編程的基本功。新項目建議全面使用 Unicode(UTF-16 `wchar_t` 或 UTF-8 `char`),避免轉換帶來的性能損耗與編碼錯誤。

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