Windows核心编程笔记(二) Widnwos下的字符处理

这一章作者首先介绍了字符编码,以及Windwos为什么使用Uincode 并使用UTF-16编码,关于字符集和字符编码参见http://blog.csdn.net/wangpengk7788/article/details/54075917


微软的编译器内建了一个wchar_t的数据类型,它表示UTF-16编码的字符,编译器需要打开 /Zc:wchar_t开关才可以使用该类型,现在的VS默认是打开的,定义Unicode字符和字符串

wchar_t   c= L"A";

whcar_t   buffer[100] = L"A String0";

微软为区别C/C++为字符类型做了一些扩展定义,在WINNT.H文件中

#ifndef _MAC
typedef wchar_t WCHAR;    // wc,   16-bit UNICODE character
#else
// some Macintosh compilers don't define wchar_t in a convenient location, or define it as a char
typedef unsigned short WCHAR;    // wc,   16-bit UNICODE character
#endif

typedef WCHAR *PWCHAR, *LPWCH, *PWCH;
typedef CONST WCHAR *LPCWCH, *PCWCH;

typedef __nullterminated WCHAR *NWPSTR, *LPWSTR, *PWSTR;
typedef __nullterminated PWSTR *PZPWSTR;
typedef __nullterminated CONST PWSTR *PCZPWSTR;
typedef __nullterminated WCHAR UNALIGNED *LPUWSTR, *PUWSTR;
typedef __nullterminated CONST WCHAR *LPCWSTR, *PCWSTR;
typedef __nullterminated PCWSTR *PZPCWSTR;
typedef __nullterminated CONST WCHAR UNALIGNED *LPCUWSTR, *PCUWSTR;

typedef __nullnullterminated WCHAR *PZZWSTR;
typedef __nullnullterminated CONST WCHAR *PCZZWSTR;
typedef __nullnullterminated WCHAR UNALIGNED *PUZZWSTR;
typedef __nullnullterminated CONST WCHAR UNALIGNED *PCUZZWSTR;

typedef __possibly_notnullterminated WCHAR *PNZWCH;
typedef __possibly_notnullterminated CONST WCHAR *PCNZWCH;
typedef __possibly_notnullterminated WCHAR UNALIGNED *PUNZWCH;
typedef __possibly_notnullterminated CONST WCHAR UNALIGNED *PCUNZWCH;

#if _WIN32_WINNT >= 0x0600 || (defined(__cplusplus) && defined(WINDOWS_ENABLE_CPLUSPLUS))

typedef CONST WCHAR *LPCWCHAR, *PCWCHAR;
typedef CONST WCHAR UNALIGNED *LPCUWCHAR, *PCUWCHAR;

typedef char CHAR;
typedef CHAR *PCHAR, *LPCH, *PCH;
typedef CONST CHAR *LPCCH, *PCCH;

typedef __nullterminated CHAR *NPSTR, *LPSTR, *PSTR;
typedef __nullterminated PSTR *PZPSTR;
typedef __nullterminated CONST PSTR *PCZPSTR;
typedef __nullterminated CONST CHAR *LPCSTR, *PCSTR;
typedef __nullterminated PCSTR *PZPCSTR;

typedef __nullnullterminated CHAR *PZZSTR;
typedef __nullnullterminated CONST CHAR *PCZZSTR;

typedef __possibly_notnullterminated CHAR *PNZCH;
typedef __possibly_notnullterminated CONST CHAR *PCNZCH;

在MSDN和VS中对含义字符串参数的API,均使用重新定义的类型来描述,如CreateFile

HANDLE WINAPI CreateFile(
  __in      LPCTSTR lpFileName,
  __in      DWORD dwDesiredAccess,
  __in      DWORD dwShareMode,
  __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  __in      DWORD dwCreationDisposition,
  __in      DWORD dwFlagsAndAttributes,
  __in_opt  HANDLE hTemplateFile
);

为了在Windwos下编程使代码可维护性增强,应该坚持并统一使用Windows数据类型,比较MSDN文档中的描述都使用这些类型。

另外VS中还定义了这样的宏


#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)

这样我们编写


TCHAR c = TEXT('A');

TCHAR Buffer[100] = TEXT("A String");


无论在ANSI还是Unicode模式下 都可以编译通过




Windows的API函数如果有字符串参数的,都存在两个版本,例如CreateFile函数在winbase.h中是这样定义的

 

#define CreateFile  CreateFileW
#else
#define CreateFile  CreateFileA
#endif // !UNICODE
      这样的API函数有两个版本分别对应ANSI和Unicode模式,他们都由系统的DLL文件导出,在内部实现中,后缀是A的函数申请了一块内存然后将ANSI字符串转化成Unicode字符串保存到该块Buffer,然后以该Buffer的地址作为参数,调用后缀是W的函数,并在函数返回时释放该Buffer,只所以这样做是因为Windwos的内核实现中都是使用Unicode字符编码的,因此我们在写Windows应用程序时应首先考虑使用Unicode宽字符集,来避免调用A后缀的函数带来的资源开销。

在使用C运行库时,每个字符串相关函数同样存在两个版本,但是与Windows API函数不同,每个版本的函数都是独立实现的。在旧的C标准库函数中,对字符串修改的函数如strcpy  wcscpy因为没有指定缓冲区长度,很可能造成缓冲区溢出,因此在编程时不要使用这些存在安全隐患的C标准库函数是一个好的习惯。


Windows为这些不安全的C标准库函数提供了对应的安全版本,声明在StrSage.h文件中,这些函数都在原函数后加上_s后缀来做为新的函数名,如strcpy_s,这些新版本的函数,会检查传入的参数是否有效,缓冲区是否能容纳结果,如果检查失败,都会设置局部于线程的C运行时变量errno,并返回errno_t指示函数失败,同时C运行库运行我们设置一个自己的回调函数,在检查失败是调用该函数,可以这样定义该函数


       void invalid_parameter_handler(const wchar_t *, const wchar_t *, const wchar_t *, unsigned int, uintptr_t); 


然后调用_set_invalid_parameter_handler来注册这个回调函数,这里其实是设置一个全局函数指针,参见http://blog.csdn.net/wangpengk7788/article/details/53938305

     这些函数的使用可以参考MSDN,除此之外C运行库还提供可一些函数,在处理字符串是提供更多地控制,如用自己填充,复制时截断,



使用参见MSDN   另外Windwos在kernerl32.dll中也导出了一些自出了一些字符串处理函数,作者介绍和向我们推荐了 CompareString(Ex)函数,使用一并参考MSDN吧






最后是用于Unicode 和 ANSI 字符之间转换的函数 MultiByteToWideChar  和 WideCharToMultiByte 使用可以百度 或者 MSDN  


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值