单字节和双字节字符示例:
#include
<
string
.h
>
#include
<
locale.h
>
#include
<
stdio.h
>
#include
<
stdlib.h
>
#include
<
mbstring.h
>
int
main()
{
char* str1 = "Count.";
wchar_t* wstr1 = L"Count.";
char * mbstr1;
char * locale_string;
// strlen gives the length of single-byte character string
printf("Length of '%s' : %d\n", str1, strlen(str1) );
// wcslen gives the length of a wide character string
wprintf(L"Length of '%s' : %d\n", wstr1, wcslen(wstr1) );
// A multibyte string: [A] [B] [C] [katakana A] [D] [\0]
// in Code Page 932. For this example to work correctly,
// the Japanese language support must be enabled by the
// operating system.
mbstr1 = "ABC" "\x83\x40" "D";
locale_string = setlocale(LC_CTYPE, "Japanese_Japan");
if (locale_string == NULL)
{
printf("Japanese locale not enabled. Exiting.\n");
exit(1);
}
else
{
printf("Locale set to %s\n", locale_string);
}
// _mbslen will recognize the Japanese multibyte character if the
// current locale used by the operating system is Japanese
printf("Length of '%s' : %d\n", mbstr1, _mbslen((const unsigned char*)mbstr1) );
// _mbstrlen will recognize the Japanese multibyte character
// since the CRT locale is set to Japanese even if the OS locale
// isnot.
printf("Length of '%s' : %d\n", mbstr1, _mbstrlen(mbstr1) );
printf("Bytes in '%s' : %d\n", mbstr1, strlen(mbstr1) );
system("pause");
}
此外,windows还提供了一些函数来帮助我们对DBCS进行操作,比如CharPrev, CharNext, IsDBCSLeadByte等。
你应该知道的:
1) Windows 2000既支持Unicode,也支持ANSI,因此可以为任意一种开发应用程序。
2)Windows 98只支持ANSI,只能为ANSI开发应用程序。
3) Windows CE只支持Unicode,只能为Unicode开发应用程序。
4)当Microsoft公司将COM从1 6位Windows转换成Win32时,公司作出了一个决定,即需要字符串的所有COM接口方法都只能接受Unicode字符串。
要支持Unicode,只需要定义两个宏(UNICODE和_UNICODE),就可以修改然后重新编译该源文件。
C运行时库也添加了对Unicode的支持,定义了wchat_t及相关的处理函数,如wcscat,wcschr,wcscpy,wcslen等。
但为了能建立ANSI/Unicode通用代码,不应该直接调用str函数或wcs函数,而是应该使用一组宏,若定义了_UNICODE,就引用wsc这组函数,若没有,则引用str这组函数。例如,_tcscpy这个宏,若定义了_UNICODE,就扩展为wcscpy,若没有,则扩展为strcpy。
TCHAR
*
szCh
=
_TEXT(
"
error
"
);
if
(szCh[
0
]
==
_TEXT(
'
e
'
))
{
printf("ok");
}
WHAR Unicode字符
PWSTR 指向Unicode字符串的指针
PCWSTR 指向一个恒定的Unicode字符串的指针
这些数据类型是指Unicode字符和字符串。Windows头文件也定义了A N S I / Unicode通用数据类型PTSTR和PCTSTR。这些数据类型既可以指A N S I字符串,也可以指Unicode字符串,这取决于当编译程序模块时是否定义了Unicode宏。这里的Unicode宏没有前置的下划线。_Unicode宏用于C运行期头文件,而Unicode宏则用于Windows头文件。当编译源代码模块时,通常必须同时定义这两个宏。
• 将文本串视为字符数组,而不是chars数组或字节数组。
• 将通用数据类型(如TCHAR和PTSTR)用于文本字符和字符串。
• 将显式数据类型(如BYTE和PBYTE)用于字节、字节指针和数据缓存。
• 将TEXT宏用于原义字符和字符串。
• 执行全局性替换(例如用PTSTR替换PSTR)。
• 修改字符串运算问题。例如函数通常希望你在字符中传递一个缓存的大小,而不是字节。
这意味着你不应该传递sizeof (szBuffer ) ,而应该传递( sizeof (szBuffer ) / sizeof (TCHAR )。另外,如果需要为字符串分配一个内存块,并且拥有该字符串中的字符数目,那么请记住要按字节来分配内存。这就是说,应该调用malloc(nCharacters *sizeof(TCHAR)), 而不是调用malloc( nChar)
Windows也提供了一组用于对Unicode字符串进行操作的函数
lstrcat 将一个字符串置于另一个字符串的结尾处
lstrcmp 对两个字符串进行区分大小写的比较
lstrcmpi 对两个字符串进行不区分大小写的比较
lstrcpy 将一个字符串拷贝到内存中的另一个位置
lstrlen 返回字符串的长度(按字符数来计量)
C运行期函数strcmp、strcmp i、wcscmp和wcscmpi只是对字符串中的代码点的值进行比较,这就是说,这些函数将忽略实际字符的含义,只是将第一个字符串中的每个字符的数值与第二个字符串中的字符的数值进行比较。而Windows函数lstrcmp和lstrcmpi是作为对Windows函数CompareString的调用来实现的。
int
CompareString(
LCID Locale,
DWORD dwCmpFlags,
LPCTSTR lpString1,
int
cchCount1,
LPCTSTR lpString2,
int
cchCount2
);
该函数对两个Unicode字符串进行比较。CompareString的第一个参数用于设定语言I D(LCID),这是个32位值,用于标识一种特定的语言。CompareString使用这个LCID来比较这两个字符串,方法是对照一种特定的语言来查看它们的字符的含义
LCID GetThreadLocale(void);
当lstrcmp函数系列中的任何一个函数调用CompareString时,该函数便将调用Windows的GetThreadLocale函数的结果作为第一个参数来传递:每次创建一个线程时,它就被赋予一种语言。函数将返回该线程的当前语言设置。
#include
<
windows.h
>
#include
<
tchar.h
>
#include
<
stdio.h
>
int
CDECL MessageBoxPrintf (TCHAR
*
szCaption, TCHAR
*
szFormat, )
{
TCHAR szBuffer [1024] ;
va_list pArgList ;
// The va_start macro (defined in STDARG.H) is usually equivalent to:
// pArgList = (char *) &szFormat + sizeof (szFormat) ;
va_start (pArgList, szFormat) ;
// The last argument to wvsprintf points to the arguments
_vsntprintf ( szBuffer, sizeof (szBuffer) / sizeof (TCHAR),
szFormat, pArgList) ;
// The va_end macro just zeroes out pArgList for no good reason
va_end (pArgList) ;
return MessageBox (NULL, szBuffer, szCaption, 0) ;
}
int
WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine,
int
iCmdShow)
{
int cxScreen, cyScreen ;
cxScreen = GetSystemMetrics (SM_CXSCREEN) ;
cyScreen = GetSystemMetrics (SM_CYSCREEN) ;
MessageBoxPrintf ( TEXT ("ScrnSize"),
TEXT ("The screen is %i pixels wide by %i pixels high."),
cxScreen, cyScreen) ;
return 0 ;
}