Linux 與 Windows 對於字符及字符串(無論是否 UNICODE模式)基本處理函數接口都遵循 POSIX標准,是一致的。Windows在這個基礎上還在TCHAR.h中封裝了自己的一個接口定義,以利於用 UNICODE宏就可以讓程序在不同的環境中運行。
原本非UNICODE定義基於 char 類型,UNICODE定義基於 wchar_t 類型, Windows 在winnt.h中分別定義兩個宏來代表這兩種類型,
typedef char CHAR;
#ifndef _MAC
typedef wchar_t WCHAR; // wc, 16-bit UNICODE character
#else
// some Macintosh compilers don't define wchar_t in a convenient location, or define it as a char
typedef unsigned short WCHAR; // wc, 16-bit UNICODE character
#endif
然後基於以上定義定義了一系列 TCHAR 宏,這樣,可以讓你的程序輕松地在 UNICODE 及 非 UNICODE環境之間移植,你只要使用 TCHAR相關的宏定義
在定義 wcs(wide char string 縮寫) 常量時,需要使用L 前綴的字符串常量,如。
wchar_t mywstring = L "my wide char string";
Windows 也提供了相應的封裝宏定義 __T。
#ifdef UNICODE
#define __T(x) L ## x
...
#else
#define __T(x) x
...
#endif
在編程時,你應該使用 _T 或 _TEXT,他們都一樣
/* Generic text macros to be used with string literals and character constants.
Will also allow symbolic constants that resolve to same. */
#define _T(x) __T(x)
#define _TEXT(x) __T(x)
當編譯參數UNICODE有定義時,定義 _tcs* 字符串宏如下,其中函數或宏名字以"_"開頭可以理解為不屬於 POSIX 范圍,亦即 linux中找不到相應函數。
#ifdef UNICODE
。。。略
/* String functions */
#define _tcscat wcscat
#define _tcschr wcschr
#define _tcscpy wcscpy
#define _tcscspn wcscspn
#define _tcslen wcslen
#define _tcsncat wcsncat
#define _tcsncpy wcsncpy
#define _tcspbrk wcspbrk
#define _tcsrchr wcsrchr
#define _tcsspn wcsspn
#define _tcsstr wcsstr
#define _tcstok wcstok
#define _tcsdup _wcsdup
#define _tcsnset _wcsnset
#define _tcsrev _wcsrev
#define _tcsset _wcsset
#define _tcscmp wcscmp
#define _tcsicmp _wcsicmp
#define _tcsnccmp wcsncmp
#define _tcsncmp wcsncmp
#define _tcsncicmp _wcsnicmp
#define _tcsnicmp _wcsnicmp
#define _tcscoll wcscoll
#define _tcsicoll _wcsicoll
#define _tcsnccoll _wcsncoll
#define _tcsncoll _wcsncoll
#define _tcsncicoll _wcsnicoll
#define _tcsnicoll _wcsnicoll
。。。略
當沒有 UNICODE 定義時,_tcs* 宏定義指向普通操作
#else /* ndef _UNICODE */
。。。略
#define _tcscat strcat
#define _tcscpy strcpy
#define _tcsdup _strdup
#define _tcslen strlen
。。。略
#ifdef _MBCS
。。。略
#define _tcschr _mbschr
#define _tcscspn _mbscspn
#define _tcsncat _mbsnbcat
#define _tcsncpy _mbsnbcpy
#define _tcspbrk _mbspbrk
#define _tcsrchr _mbsrchr
#define _tcsspn _mbsspn
#define _tcsstr _mbsstr
#define _tcstok _mbstok
#define _tcsnset _mbsnbset
#define _tcsrev _mbsrev
#define _tcsset _mbsset
#define _tcscmp _mbscmp
#define _tcsicmp _mbsicmp
#define _tcsnccmp _mbsncmp
#define _tcsncmp _mbsnbcmp
#define _tcsncicmp _mbsnicmp
#define _tcsnicmp _mbsnbicmp
。。。略
#else /* !_MBCS */
。。。略
#define _tcschr strchr
#define _tcscspn strcspn
#define _tcsncat strncat
#define _tcsncpy strncpy
#define _tcspbrk strpbrk
#define _tcsrchr strrchr
#define _tcsspn strspn
#define _tcsstr strstr
#define _tcstok strtok
#define _tcsnset _strnset
#define _tcsrev _strrev
#define _tcsset _strset
#define _tcscmp strcmp
#define _tcsicmp _stricmp
#define _tcsnccmp strncmp
#define _tcsncmp strncmp
#define _tcsncicmp _strnicmp
#define _tcsnicmp _strnicmp
。。。略
#endif
#endif
可以注意到 ,_strnicmp 在linux 中對應 strncasecmp,而 _wcsnicmp 在linux中我沒有找到相應功能函數。對於打開文件操作,如果文件名是以 UNICODE 格式存儲的,在 MSVC2005之前使用 _tfopen 這個宏,在MSVC 2005 出現之後,你可以在第二個參數中使用 “ccs:UNICODE”來指定,如。FILE *fp = fopen(FILENAME, "rb,ccs=UNICODE");linux可能早已支持這種參數形式,可以參考linux man:fopen(3).如果沒有指定ccs,linux將以你使用的第一個文件操作函數是 UNICODE的還是 非UNICODE 的來決定。(,ccs=string
The given string is taken as the name of a coded character set and the stream is marked as wide-oriented. Thereafter, internal conversion functionsconvert I/O to and from the character setstring. If the ,ccs=string syntax is not specified, then the wide-orientation of the stream isdetermined by the first file operation. If that operation is a wide-character operation, the stream is marked wide-oriented, and functions to convert to thecoded character set are loaded. )