[学习笔记]Windows程序设计:第二章 UNICODE

时间:2023-02-19 21:17:17

一、宽字符和C语言

        C语言中的宽字符是基于wchar_t数据类型的,这个数据类型被定义在多个头文件中,包括WCHAR.H

typedef unsigned short wchar_t;
wchar_t c = 'A';
wchar_t c = L'A';//也可以在单个字符常量前面使用L前缀,但这通常是不需要的。C编译器总是会在字符后面加0的。
wchar_t *pw = L"Hello!";//L(大写字母)紧接左引号。这向编译器表明这个字符串将用宽字符存储,每个字符占用2个字节。指针变量pw还是需要4个字节的存储空间。
iLength = wcslen(pw);//该函数返回的结果是6。
//wcslen函数的声明如下:
size_t __cdecl wcslen(const wchar_t*);

      Microsoft Visual C++包含的TCHAR.H表头文件中

#ifdef _UNICODE  
#define _tcslen wcslen
#else
#define _tcslen strlen
#endif

#ifdef _UNICODE
#define wchar_t TCHAR
#else
#define char TCHAR
#endif

#ifdef _UNICODE
#define __T(x) L##x
#else
#define __T(x) x
#endif

#define _T(x) __T(x)
#define _TEXT(x) __T(x)

二、宽字符和Windows

1.Windows头文件类型

typedef char CHAR;  
typedef wchar_t WCHAR;

typedef CHAR *PCHAR, *LPCH,*PCH,*NPSTR,*LPSTR,*PSTR;
typedef CONST CHAR *LPCCH,*PCCH,*LPSTR,*PSTR;
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

2.Windows函数调用

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

3.Windows的字符串函数

       是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) ;

4.在Windows中使用printf

       在windows编程中不能使用pirntf,但能使用sprintf,vsprintf系列

int sprintf( char *buffer, const char *format [,argument] ... );
int vsprintf( char *buffer, const char *format, va_list argptr );

      sprintf的第一个参数是一个字符缓冲区;后面是一个格式字符串。sprintf并不是将格式化结果写到标准输出,面是将其存入buffer。该函数返回该字符串的长度。在字符模式编程环境中,语句:

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来显示结果。
      vsprintf是sprintf的变形函数,它只有三个参数。vsprintf的前两个参数与sprintf相同,第三个参数是指向待格式化的参数数组的指针,该指针指向在堆栈*函数调用的变量。宏va_list、va_start和va_end(在STDARG.H中定义)帮助处理堆栈指针。查阅STDARG.H中宏va_list、va_start和va_end的定义。
        (这里不怎么懂,先写上,以后再回头看。参考博文:http://blog.csdn.net/udnova/article/details/551471)

#ifndef _VA_LIST_DEFINED
#ifdef _M_ALPHA
typedef struct
{
char *a0; /* pointer to first homed integer argument */
int offset; /* byte offset of next parameter */
} va_list;
#else
typedef char * va_list;
#endif
#define _VA_LIST_DEFINED
#endif

#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )
       vsprintf和sprintf使用时有两个要注意的地方:
      1.与printf一样当格式字符串与被格式化的变量不匹配时,可能会运行错误并可能造成程序崩溃。
      2.用户的自定义的字符缓冲区必须足够大来存放结果,否则会造成缓冲区溢出(非法内存访问)。
       所以由此引申出它们的第一个变种:最大长度版

int _snprintf( char *buffer, size_t count, const char *format [, argument] ... );
int _vsnprintf( char *buffer, size_t count, const char *format, va_list argptr );