tchar.h 中的一般文本映射
为了传输代码供国际使用,Microsoft 运行时库为许多数据类型、例程和其他对象提供了 Microsoft 专用的一般文本映射。 你可使用这些映射(定义见 tchar.h)来编写可为单字节、多字节或 Unicode 字符集编译的泛型代码,具体取决于使用 #define
语句定义的清单常量。 一般文本映射是与 ANSI 不兼容的 Microsoft 扩展。
通过使用 tchar.h,可从相同的源生成单字节、多字符集 (MBCS) 和 Unicode 应用程序。 tchar.h 定义了具有前缀 _tcs
的宏,这些宏通过正确的预处理器定义,根据情况映射到 str
、_mbs
或 wcs
函数。 若要生成 MBCS,请定义符号 _MBCS
。 若要生成 Unicode,请定义符号 _UNICODE
。 若要生成单字节应用程序,则两者都不定义(默认设置)。 默认情况下,为 MFC 应用程序定义 _UNICODE
。
_TCHAR
数据类型在 tchar.h 中有条件地定义。 如果为生成定义了符号 _UNICODE
,则 _TCHAR
定义为 wchar_t
;否则,对于单字节和 MBCS 生成,则将其定义为 char
。 (wchar_t
是基本 Unicode 宽字符数据类型,它是与 8 位 signed char
相对应的 16 位。)对于国际应用程序,请使用 _tcs
函数系列,它以 _TCHAR
单位(而不是字节)运行。 例如,_tcsncpy
复制 n
个 _TCHARs
,而不是 n
个字节。
由于某些单字节字符 (SBCS) 字符串处理函数采用(带符号的)char*
参数,因此定义 _MBCS
时,编译器会发出类型不匹配的警告。 有三种方法来避免此警告:
使用 tchar.h 中类型安全的内联函数。 此选项为默认行为。
通过在命令行上定义
_MB_MAP_DIRECT
,使用 tchar.h 中直接的宏。 如果执行此操作,必须手动匹配类型。 这是最快的方法,但不是类型安全的方法。使用 tchar.h 中类型安全的静态链接的库函数 thunk。 为此,在命令行上定义常量
_NO_INLINING
。 这是最慢的方法,但是最能确保类型安全。
用于一般文本映射的预处理器指令
# define | 编译的版本 | 示例 |
---|---|---|
_UNICODE |
Unicode(宽字符) | _tcsrev 映射到 _wcsrev |
_MBCS |
多字节字符 | _tcsrev 映射到 _mbsrev |
无(默认设置是未定义 _UNICODE 和 _MBCS ) |
SBCS (ASCII) | _tcsrev 映射到 strrev |
例如,如果已在程序中定义了 _MBCS
,则在 tchar.h 中定义的一般文本函数 _tcsrev
映射到 _mbsrev
;如果定义了 _UNICODE
,则映射到 _wcsrev
。 否则,_tcsrev
将映射到 strrev
。 为了便于编译,tchar.h 中提供了其他数据类型映射,但 _TCHAR
是最有用的。
一般文本数据类型映射
一般文本 数据类型名称 |
_UNICODE & 未定义 _MBCS |
_MBCS 已定义 |
_UNICODE 已定义 |
---|---|---|---|
_TCHAR |
char |
char |
wchar_t |
_TINT |
int |
unsigned int |
wint_t |
_TSCHAR |
signed char |
signed char |
wchar_t |
_TUCHAR |
unsigned char |
unsigned char |
wchar_t |
_TXCHAR |
char |
unsigned char |
wchar_t |
_T 或 _TEXT |
无效果(由预处理器删除) | 无效果(由预处理器删除) | L (将以下字符或字符串转换为其 Unicode 对应项) |
有关例程、变量和其他对象的一般文本映射的完整列表,请查看运行时库参考中的一般文本映射。
注意
不要将 str
函数系列与 Unicode 字符串一起使用,这些字符串可能包含嵌入的 null 字节。 同样,不要将 wcs
函数系列与 MBCS(或 SBCS)字符串一起使用。
以下代码片段说明了用于映射到 MBCS、Unicode 和 SBCS 模型的 _TCHAR
和 _tcsrev
的使用方法。
_TCHAR *RetVal, *szString;
RetVal = _tcsrev(szString);
如果定义了 _MBCS
,则预处理器将此片段映射到以下代码:
char *RetVal, *szString;
RetVal = _mbsrev(szString);
如果定义了 _UNICODE
,则预处理器将此片段映射到以下代码:
wchar_t *RetVal, *szString;
RetVal = _wcsrev(szString);
如果 _MBCS
和 _UNICODE
均未定义,则预处理器将片段映射到单字节 ASCII 代码,如下所示:
char *RetVal, *szString;
RetVal = strrev(szString);
因此,可编写、维护和编译单个源代码文件,来与特定于三种字符集中任何一种的例程一起运行。