隨著國際化需求增長,C 語言透過 wchar_t 與寬字符函數族支援 Unicode。本文整理標準庫對應關係、多位元組/寬字符轉換、以及 ANSI/Unicode 雙模式開發要點。
| 分類 | 寬字符函數 | 對應 ANSI 函數 | 功能 |
|---|---|---|---|
| 字符分類 | iswalnum | isalnum | 字母數字判斷 |
iswalpha | isalpha | 字母判斷 | |
iswcntrl | iscntrl | 控制字符判斷 | |
iswdigit | isdigit | 數字判斷 | |
iswgraph | isgraph | 可見字符判斷 | |
iswlower | islower | 小寫判斷 | |
iswprint | isprint | 可列印判斷 | |
iswpunct | ispunct | 標點判斷 | |
iswspace | isspace | 空白判斷 | |
iswupper | isupper | 大寫判斷 | |
iswxdigit | isxdigit | 十六進制數字判斷 | |
| 大小寫轉換 | towlower | tolower | 轉小寫 |
towupper | toupper | 轉大寫 | |
| 字符串比較/排序 | wcscoll | strcoll | 按當前 locale 比較 |
wcsftime | strftime | 格式化時間 (寬字符輸出) | |
wcsftime | - | 寬字符版時間格式化 | |
| 格式化 I/O | fwprintf | fprintf | 檔案格式化寫入 |
fwscanf | fscanf | 檔案格式化讀取 | |
wprintf | printf | 標準輸出格式化寫入 | |
wscanf | scanf | 標準輸入格式化讀取 | |
swprintf | sprintf | 字符串格式化寫入 | |
swscanf | sscanf | 字符串格式化讀取 | |
vfwprintf | vfprintf | va_list 版檔案輸出 | |
| 數值轉換 | wcstod | strtod | 字符串轉 double |
wcstol | strtol | 字符串轉 long | |
wcstoul | strtoul | 字符串轉 unsigned long | |
| 多位元組/寬字符轉換 | mblen | - | 多位元組字符長度 |
mbstowcs | - | 多位元組串轉寬字符串 | |
mbtowc/btowc | - | 單字符轉寬字符 | |
wcstombs | - | 寬字符串轉多位元組串 | |
wctomb/wctob | - | 寬字符轉多位元組 | |
| 檔案/流 I/O | fgetwc | fgetc | 讀取寬字符 |
fgetws | fgets | 讀取寬字符串 | |
fputwc | fputc | 寫入寬字符 | |
fputws | fputs | 寫入寬字符串 | |
getwc | getc | 標準輸入讀寬字符 | |
getwchar | getchar | 標準輸入讀寬字符 | |
putwc | putc | 標準輸出寫寬字符 | |
putwchar | putchar | 標準輸出寫寬字符 | |
ungetwc | ungetc | 回推寬字符到流 | |
| 字符串操作 | wcscat | strcat | 字符串拼接 |
wcsncat | strncat | 指定長度拼接 | |
wcschr | strchr | 查找字符首次出現 | |
wcsrchr | strrchr | 反向查找字符 | |
wcspbrk | strpbrk | 查找任一字符集首次出現 | |
wcsstr | strstr | 查找子串首次出現 | |
wcscspn | strcspn | 不含指定字符集的初始長度 | |
wcsspn | strspn | 僅含指定字符集的初始長度 | |
wcscpy | strcpy | 字符串複製 | |
wcsncpy | strncpy | 指定長度複製 | |
wcscmp | strcmp | 字符串比較 | |
wcsncmp | strncmp | 指定長度比較 | |
wcslen | strlen | 字符串長度 | |
| 記憶體操作 | wmemcpy | memcpy | 記憶體複製 |
wmemmove | memmove | 記憶體移動 | |
wmemcmp | memcmp | 記憶體比較 | |
wmemchr | memchr | 記憶體查找字符 | |
wmemset | memset | 記憶體設置 |
// 多位元組字符串 -> 寬字符串
size_t mbstowcs(wchar_t *pwcs, const char *s, size_t n);
// 寬字符串 -> 多位元組字符串
size_t wcstombs(char *s, const wchar_t *pwcs, size_t n);
// 單字符轉換 (受 locale 影響)
int mbtowc(wchar_t *pwc, const char *s, size_t n);
int wctomb(char *s, wchar_t wchar);
// 判斷多位元組字符長度
int mblen(const char *s, size_t n);
關鍵點:轉換行為由當前 LC_CTYPE locale 決定。UTF-8 locale 下可正確處理中文;"C" locale 下多位元組字符長度通常為 1,無法正確轉換非 ASCII 字符。
Windows 平台透過宏切換:
UNICODE (Windows SDK) 與 _UNICODE (CRT) → 啟用寬字符版本通用類型映射:
| 宏定義 | UNICODE=1 | UNICODE=0 |
|---|---|---|
TCHAR | wchar_t | char |
LPTSTR | LPWSTR | LPSTR |
LPCTSTR | LPCWSTR | LPCSTR |
| 字符串字面值 | L"text" / _T("text") | "text" |
| 字符串函數 | wcscpy, _tcscpy | strcpy, _tcscpy |
使用 _T() 或 TEXT() 宏包裹字面值,配合 _tcs* 通用函數,可實現單一代碼庫雙模式編譯。
char*),避免 wchar_t 大小不一 (Windows 2 bytes, Linux 4 bytes) 導致的二進制不相容W 結尾,如 CreateFileW),避免 ANSI 版隱含轉換效能損耗wchar_t 不是固定 2 字節:C 標準僅保證能容納基本字符集,實際大小由實現定義setlocale(LC_ALL, "") 必須在多位元組函數調用前執行,否則行為未定義