第二章 Unicode简介(1)
来源:互联网 发布:旋转木马js效果带左右 编辑:程序博客网 时间:2024/04/28 14:42
在标准C中,通过一种叫“宽字符”的概念来支持用多个字节代表一个字符的字符集。多字节字符集主要影响C语言运行库函数。宽字符并不一定是Unicode。Unicode只是宽字符编码的一种实现。我们进在Windows中,将宽字符和Unicode作为同义词。
更宽的字符
使用Unicode或者是宽字符并不会改变C语言中的字符数据类型。C语言中的宽字符是基于wchar_t数据类型的。这个数据类型被定义在多个头文件中。包括WCHAR.H,如下所示:
typedef unsigned short wchar_t;
可以用下面的语句来定义一个包含单个宽字符的变量:
wchar_t c = 'A';
也可以在单个字符串常量前面使用L前缀,如下所示,以表明它们应被解释为宽字符:
wchar_t c = L'A';
但这通常是不需要的,C编译器总是会在字符后面加0的。
还可以如下定义一个已初始化的指向宽字符串的指针:
wchar_t *p = L"Hello!";
宽字符的库函数
宽字符版本的strlen函数被称为wcslen,并定义在STRING.H和WCHAR.H中,strlen函数的声明如下:
size_t __cdecl strlen( const char *);
而wcslen函数的声明如下:
size_t __cdecl wcslen( const wchar_t *);
在使用宽字符的时候,字符串的字符长度并没有改变,改变的只是字节长度。
维护一个源代码文件
维护一个单一源代码文件,使之可以编译成ASCII或Unicde。其中一个方法是使用包含在VC中的TCHAR.H头文件。这个头文件并不是ANSI C标准的一部分,所以其中定义的每一个函数和宏都有一个下划线前缀。TCHAR.H为那些需要字符串参数的普通运行库函数(例如,_tprintf和_tcslen)提供了一系列的替代名称。这些函数有时被称为“通用”的函数名字,因为它们可以指定Unicode或非Unicode版本的函数。
如下定义,其中那一堆数字符号被称为“令牌粘贴”,它使得字母L和红参数拼接在一起。
#ifdef _UNICODE
typedef wchar_t TCHAR;
#define _tcslen wcslen
#define __T(x) L##x
#else
typedef char TCHAR;
#defin _tcslen strlen
#define __T(x) x
#endif
#define _T(x) __T(x)
#define _TEXT(x) __T(x)
Windows头文件的类型
Windows程序包含着WINDOWS.H头文件,该文件又包含着许多其他头文件,例如WINDEF.H,该文件中又有许多在Windows中使用的基本数据类型的定义,同时它本身也包含WINNT.H。WINNT.H则负责处理基本的Unicde支持功能。
WINNT.H在一开始就包含C的头文件CTYPE.H,而着是C的众多头文件之一,包含着wchar_t 的定义。WINNT.H定义了两个新的被称作CHAR和WCAHR的数据类型:
typedef char CHAR;
typedef wcahr_t WCHAR; //wc是匈牙利标记法,用来说明这是一个宽字符。
CHAR和WCHAR是写Windows程序时推荐使用的数据类型,它们分别用于定义8位或者16位的字符。WINNT.H将TCHAR定义为一个通用的字符类型。如果标识符UNICODE(没有下划线)被定义了,则TCHAR 和指向TCHAR的指针就被定义为WCHAR和指向WCHAR的指针;如果标识符UNICODE没有被定义,则TCHAR和指向TCHAR的指针就分别被定义为char和指向char的指针。WINNT.H头文件还定义了一个宏,它将L添加到一个字符串的第一个引号前。定义如下:
#ifdef UNICODE
typedef WCHAR TCHAR , * PTCHAR;
#define __TEXT(quote) L##quote
#else
typedef char TCHAR , * PTCHAR;
#define __TEXT(quote) quote
#endif
#define TEXT(quote) __TEXT(quote)
Windows函数调用
如果需要在程序中混合调用并匹配ASCII和宽字符函数,则可以明确使用MessageBoxA和MessageBoxW函数。但我们可以继续使用MessageBox。根据是否已定义UNICODE标识符,MessageBox将实际调用MessageBoxA或是MessageBoxW。如下所示:
#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif
Windows的字符串函数
Microsoft C包含宽字符以及通用版的需要字符串参数的C语言运行库函数。不过,Windows复制了其中一部分C函数。例如,下面是Windows定义的一组字符串函数,这些函数用来计算字符串长度、复制字符串、链接字符串和比较字符串:
ILength = lstrlen( pString );
pString = lstrcpy( pString1, pString2 );
pString = lstrcpyn( pString1, pString2, iCount );
pString = lstrcat( pString1, pString2 );
iComp = lstrcmp( pString1,pString2 );
iComp = lstrcmpi( pString1,pString2 );
这些函数提供了与C运行库中对应的函数功能。当定义了UNICODE标识符时,这些函数就接受宽字符串,否则只接受宽字符串。
在Windows中使用printf
Windows中不存在标准输入和标准输出的概念,所以我们可以在Windows程序中使用fprintf 函数,但不能使用printf 函数。sprintf 函数定义如下:
int sprintf ( char * szBuffer, const char * szFormat, ... );
第一个参数是一个字符串缓冲区;后面是一个格式字符串。使用sprintf 时,除了要考虑格式字符串与被格式化的变量不合外,还要考虑定义的字符串缓冲区必须足够大以存放结果。Microsoft 的专用函数 _snprintf 解决了这一问题,此函数引入一个参数来指定字符缓冲区的大小。
当需要对可变参数执行像printf 一样的格式化时,可以用vsprintf 来实现我们自己的函数。vsprintf只有三个参数,第三个参数是指向待格式化的参数数组的指针。
当然,随着宽字符的引入,sprintf系列的函数增加了许多,使得函数名让人困惑。下表列出了Microsoft版的C语言运行库和Windows所支持的所有Sprintf类函数。
ASCII 宽字符 通用 可变数目的参数 标准版 sprintf swprintf _stprintf 最大长度版 _snprintf _snwprintf _sntprintf Windows版 wsprintfA wsprintfW wsprintf 参数数组的指针 标准版 vsprintf vswprintf _vstprintf 最大长度版 _vsnprintf _vsnwprintf _vsntprintf Windows版 wvsprintfA wvsprintfW wvprintf其中最大长度版(_sntprintf和_vsntprintf)声明在TCHAR.H头文件中
————————————————————— 我是快乐的分割线 —————————————————————
包含在windows.h头文件中
类型与宏:
TCHAR pString;
TEXT(pString);
如果有定义UNICODE,则以上定义为宽字符,否则为普通的但字节字符
函数总结:
iLength = lstrlen( pString ); //计算字符串长度
pString = lstrcpy( pString1, pString2 ); //复制字符串
pString = lstrcpyn( pString1, pString2, iCount ); //复制字符串
pString = lstrcat( pString1, pString2 ); //链接字符串
iComp = lstrcmp( pString1,pString2 ); //比较字符串
iComp = lstrcmpi( pString1,pString2 ); //比较字符串
iLength = wsprintf( szBuffer,"The sum of %i and %i is %i",5,3,5+3 ); //字符串格式化函数
iLength = wvsprintf( szBuffer, szFormat, pArgList ); //字符串格式化函数(参数数组的指针)
- 第二章 Unicode简介(1)
- 第二章 Unicode简介
- 第二章 Unicode简介
- 第二章UNICODE简介
- (基础篇) 第二章 Unicode简介
- 《Windows程序设计》第二章 Unicode简介
- windows程序设计第二章-Unicode简介
- Windows Programming 第二章 Unicode简介
- 第二章 Unicode简介 sprintf 、vsprintf 、_vsntprintf
- windows程序设计:第二章:Unicode简介
- Programming Windows程式开发设计指南->第二章 Unicode简介
- 二、Unicode简介(1)
- 《Windows核心编程》第二讲 Unicode(1)Unicode介绍
- 第二章(1)WEB 页面简介
- Unicode简介(转)
- 字符集(一)-unicode简介
- 二、Unicode简介(2)
- 第二章:OSGi简介
- 网站的推广方法
- Common Problems with OgreMax 导出时的注意点
- 百度对网站主建议
- Opengl GLUT工具开发 学习笔记 001
- ajax的原理
- 第二章 Unicode简介(1)
- 跟我一起走进WPF的世界之三开发WPF用什么工具呢?
- 原创:Ajax中get与post请求详解
- Microsoft VBScript compilation error '800a0400'Expected statement/idmws/Do
- 未来移动体验(转)
- 继续学习
- VS2008 C++ 调用MATLAB 2009b 生成的DLL
- 程序中使用MATLAB编译产生的DLL (VS2005, MATLAB7.5, mwArray)
- 如何用Matlab编译.dll,再用VC调用