Unicode简介
Unicode 扩展自 ASCII,在严格的 ASCII 中,每个字节用7 位表示,或者电脑上普遍使用的每字节有 8 位;而 Unicode 使用每字节16位。Unicode 即宽字节,每个字节都是16位,共256 x 256 = 65536 个符号。前 128 个 Unicode 字符(16 位字符从 0x0000 到 0x007F)就是ASCII 字符,而接下来的 128 个 Unicode 字符(字符从 0x0080 到 0x00FF)是 ISO 8859-1 对 ASCII 的扩展。
优点:只有一个字符集。
缺点:1、相对而言,人们不习惯使用Unicode。
2、Unicode字符占用的空间是ASCII 字符的两倍。

多字节:char
宽字节:wchar_t
typedef unsigned short wchar_t
wchar_t 占用的空间与无符号短整数型态相同,都是 16 位
wchar_t c = ‘A’ ;
变数 c 是一个双位元组值 0x0041,是 Unicode 表示的字母 A。
定义指向宽字串的指针:
wchar_t * p = L"Hello!" ;
注意紧接在第一个引号前面的大写字母 L(代表【long】)。这将告诉编译
器该字串按宽字元保存——即每个字元占用 2 个位元组。
通常,指标变数 p 要占用 4 个字节,而字串变数需要 14 个字节(每个字元需要 2 个字节,末尾的 0 还需要 2个字节)。
还可以用下面的语句定义宽字元阵列:
static wchar_t a[] = L"Hello!" ;
字串也需要 14 个字节的储存空间,sizeof (a) 将返回 14。索引阵列
a 可得到单独的字元。a[1] 的值是宽字元【e】,或者 0x0065。
第一个引号前面的 L 非常重要,并且在两个符号之间必须没有空格。只有带有 L,编译器才知道您需要将字串存为每个字节 2 个字节。
在单个字节文字前面使用 L 字首,来表示它们应解释为宽字节。如
下所示:wchar_t c = L’A’ ;
但通常这是不必要的,C 编译器会对该字节进行扩充,使它成为宽字节。
计算宽字节字符串的长度:wcslen
size_t __cdecl strlen (const char *) ;
size_t __cdecl wcslen (const wchar_t *) ;

wchar_t * pw = L"Hello!" ;
iLength = wcslen (pw) ;
函式将返回字串中的字元数 6。请记住,改成宽位元组後,字串的字元长度
不改变,只是位元组长度改变了。
所有带有字串参数的 C 执行时期程式库函式都有宽字元版
wprintf 是 printf 的宽字元版
这些函式在 WCHAR.H 和含有标准函式说明的表头文件中说明

编码希望既能按 ASCII编译又能按 Unicode 编译。
1、使用 TCHAR.H 头文件函数。
TCHAR.H 为需要字串参数的标准执行时期程式库函式提供了一系列
的替代名称(例如,_tprintf 和_tcslen)这些名称也称为【通用】函式
名称,因为它们既可以指向函式的 Unicode 版也可以指向非 Unicode 版。
如果定义了名为_UNICODE 的识别字,并且程式中包含了 TCHAR.H 表头档案,那么_tcslen 就定义为 wcslen:
#define _tcslen wcslen
如果没有定义 UNICODE,则_tcslen 定义为 strlen:
#define _tcslen strlen

如果定义了 _UNICODE 识别字,那么 TCHAR 就是 wchar_t:
typedef wchar_t TCHAR ;
否则,TCHAR 就是 char:
typedef char TCHAR ;

基本地,必须按下述方法在_T 或_TEXT 巨集内定义字串文字:
_TEXT (“Hello!”)
这样做的话,如果定义了_UNICODE,那么该串将解释为宽字元的组合,否
则解释为 8 位元的字元字串。

CTYPE.H头文件。包括 wchar_t 的定义。WINNT.H 定义了新的资料型态,称作 CHAR 和 WCHAR:
typedef char CHAR ;
typedef wchar_t WCHAR ;

typedef CHAR * PCHAR, * LPCH, * PCH, * NPSTR, * LPSTR, * PSTR ;
typedef CONST CHAR * LPCCH, * PCCH, * LPCSTR, * PCSTR ;
字首 N 和 L 表示「near」和「long」,指的是 16 位元 Windows 中两种大小
不同的指标。在 Win32 中 near 和 long 指标没有区别。

typedef WCHAR * PWCHAR, * LPWCH, * PWCH, * NWPSTR, * LPWSTR, * PWSTR ;
typedef CONST WCHAR * LPCWCH, * PCWCH, * LPCWSTR, * PCWSTR ;

#ifdef UNICODE
typedef WCHAR TCHAR, * PTCHAR ;
typedef LPWSTR LPTCH, PTCH, PTSTR, LPTSTR ;
typedef LPCWSTR LPCTSTR ;
#else
typedef char TCHAR, * PTCHAR ;
typedef LPSTR LPTCH, PTCH, PTSTR, LPTSTR ;
typedef LPCSTR LPCTSTR ;
#endif

在 USER32.DLL 中,没有 32 位元MessageBox 函式的进入点。实际上,有两个进入点,一个名为 MessageBoxA (ASCII版),另一个名为 MessageBoxW(宽字元版)。
不必关心这个问题,程式中只需使用 MessageBox。与 TCHAR 表头档案一样,每个 Windows 头文件都可以解决。

WINUSERAPI int WINAPI MessageBoxA ( HWND hWnd, LPCSTR lpText,
LPCSTR lpCaption, UINT uType) ;
WINUSERAPI int WINAPI MessageBoxW (HWND hWnd, LPCWSTR lpText,
LPCWSTR lpCaption, UINT uType) ;

#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif

在 Windows 程式中不能使用 printf,在 Windows 程式中可使用 fprintf,而不是 printf。可以使用 sprintf 及 sprintf 系列中的其他函式来显示文字。这些函式除了将内容格式化输出到函式第一个参数所提供的字串缓冲区以外,其功能与 printfI 相同。然后便可对该字串进行操作。

int printf (const char * szFormat, …) ;
第一个参数是一个格式字串,後面是与格式字串中的代码相对应的不同类
型多个参数。

int sprintf (char * szBuffer, const char * szFormat, …) ;
第一个参数是字元缓冲区;后面是一个格式字串。Sprintf 不是将格式化结
果标准输出,而是将其存入 szBuffer。该函式返回该字串的长度。

printf (“The sum of %i and %i is %i”, 5, 3, 5+3) ;
的功能相同于
char szBuffer [100] ;
sprintf (szBuffer, “The sum of %i and %i is %i”, 5, 3, 5+3) ;
puts (szBuffer) ;
在 Windows 中,使用 MessageBox 显示结果优於 puts。

使用 sprintf 时,关系定义的字串缓冲区必须足够大以存放结果。_snprintf 可以解决。此函式引进了另一个参数,表示以字元计算的缓冲区大小。
vsprintf 是 sprintf 的一个变形,它只有三个参数。vsprintf 的前两个参数与 sprintf 相同:一个用于保存结果的字元缓冲区和一个格式字串。第三个参数是指向格式化参数队列的指针。
int vsprintf(char *string, char *format, va_list param);
实际上,该指针指向在堆栈中供函数调用的变量。va_list、va_start和va_end宏(在STDARG.H中定义)帮助我们处理堆栈指针。使用vsprintf 函数,sprintf 函数可以这样编写
int sprintf (char * szBuffer, const char * szFormat, …)
{
int iReturn ;
va_list pArgs ;
va_start (pArgs, szFormat) ;
iReturn = vsprintf (szBuffer, szFormat, pArgs) ;
va_end (pArgs) ;
return iReturn ;
}
va_start宏将pArg设置为指向一个堆栈变量,该变量位址在堆栈参数szFormat的上面。

列出 Microsoft 的 C 执行时期程式库和 Windows 支持的所有 sprintf 函数。
Windows 编程基础(二)

相关文章: