Windows 開發中常需在 ANSI(多字節)字符串與 Unicode(寬字符)字符串之間轉換。`sprintf` 系列處理 ANSI,`swprintf` 系列處理 Unicode。關鍵在於格式字符串與參數的字符集匹配,以及大小寫格式符號的含義差異。
| 函數 | 格式串類型 | 目標緩衝區 | %s 含義 | %S 含義 |
|---|---|---|---|---|
sprintf | ANSI (char*) | ANSI (char*) | ANSI 字符串 | Unicode → ANSI 轉換 |
swprintf | Unicode (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*`。現代代碼應使用帶 `_s` 後綴的安全版本,防止緩衝區溢出:
// C11 / VS 安全版
sprintf_s(szA, sizeof(szA), "%S", L"Unicode Str");
swprintf_s(szW, _countof(szW), L"%S", "ANSI Str");
掌握 `sprintf`/`swprintf` 的 `%s`、`%S` 語義,是 Windows 雙字符集編程的基本功。新項目建議全面使用 Unicode(UTF-16 `wchar_t` 或 UTF-8 `char`),避免轉換帶來的性能損耗與編碼錯誤。