多字符集(ANSI)和UNICODE及字符串处理方式准则
在我们编写程序的时候,使用最多的是字符串的处理,而ANSI和UNICODE的相互转换经常搞的我们头晕眼乱。
应该说UNICODE是一种比较好的编码方式,在我们的程序中应该尽量使用UNICODE编码方式,我们在编写程序的时候,最好能依据下面的准则来进行:
基本准则:
1.将文本字符串想象为字符数组,而非char或字节数组
2.开始使用通用数据类型来表示文本字符和字符串(如TCHAR,PTSTR)
原因是我们可以在WinNT.h的头文件中找到如下定义(代码有删改):
- #ifndef VOID
- #define VOID void
- typedef char CHAR;
- typedef short SHORT;
- typedef long LONG;
- typedef int INT;
- #endif
- #endif
- //
- // UNICODE (Wide Character) types
- //
- #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 WCHAR *NWPSTR, *LPWSTR, *PWSTR;
- typedef PWSTR *PZPWSTR;
- typedef CONST PWSTR *PCZPWSTR;
- typedef WCHAR UNALIGNED *LPUWSTR, *PUWSTR;
- typedef CONST WCHAR *LPCWSTR, *PCWSTR;
- typedef PCWSTR *PZPCWSTR;
- typedef CONST WCHAR UNALIGNED *LPCUWSTR, *PCUWSTR;
- typedef CONST WCHAR *LPCWCHAR, *PCWCHAR;
- typedef CONST WCHAR UNALIGNED *LPCUWCHAR, *PCUWCHAR;
- //
- // UCS (Universal Character Set) types
- //
- typedef unsigned long UCSCHAR;
- #define UCSCHAR_INVALID_CHARACTER (0xffffffff)
- #define MIN_UCSCHAR (0)
- //
- // ANSI (Multi-byte Character) types
- //
- typedef CHAR *PCHAR, *LPCH, *PCH;
- typedef CONST CHAR *LPCCH, *PCCH;
- typedef CHAR *NPSTR, *LPSTR, *PSTR;
- typedef PSTR *PZPSTR;
- typedef CONST PSTR *PCZPSTR;
- typedef CONST CHAR *LPCSTR, *PCSTR;
- typedef PCSTR *PZPCSTR;
- //
- // Neutral ANSI/UNICODE types and macros
- //
- #ifdef UNICODE // r_winnt
- #ifndef _TCHAR_DEFINED
- typedef WCHAR TCHAR, *PTCHAR;
- typedef WCHAR TBYTE , *PTBYTE ;
- #define _TCHAR_DEFINED
- #endif /* !_TCHAR_DEFINED */
- typedef LPWCH LPTCH, PTCH;
- typedef LPWSTR PTSTR, LPTSTR;
- typedef LPCWSTR PCTSTR, LPCTSTR;
- typedef LPUWSTR PUTSTR, LPUTSTR;
- typedef LPCUWSTR PCUTSTR, LPCUTSTR;
- typedef LPWSTR LP;
- #define __TEXT(quote) L##quote // r_winnt
- #else /* UNICODE */ // r_winnt
- #ifndef _TCHAR_DEFINED
- typedef char TCHAR, *PTCHAR;
- typedef unsigned char TBYTE , *PTBYTE ;
- #define _TCHAR_DEFINED
- #endif /* !_TCHAR_DEFINED */
- typedef LPCH LPTCH, PTCH;
- typedef LPSTR PTSTR, LPTSTR, PUTSTR, LPUTSTR;
- typedef LPCSTR PCTSTR, LPCTSTR, PCUTSTR, LPCUTSTR;
- #define __TEXT(quote) quote // r_winnt
- #endif /* UNICODE */ // r_winnt
3.用明确的数据类型来表示字节,字节指针和数据缓冲区(如BYTE, PBYTE)原因如上同
4.使用TEXT或是_T来表示字面量字符和字符串(这两个宏会根据你自己设置的字符集属性,动态转换成相应的字符集)
5.执行全局替换,原因同2.
6.修改与字符串有关的计算。如有些函数需要我们传入缓冲区大小的字符数,这个时候就需要_countof(szBuffer),而不是sizeof(szBuffer);
有些时候我们需要为一个字符串分配内存,那么内存是使用字节数来分配的,这个时候我们就需要使用malloc(nCharacters*sizeof(TCHAR)),而不是使用malloc(nCharacters).
我们可以使用如下样式的宏来处理这个问题:
- #define chmalloc(nCharacters) (TCHAR*)malloc(nCharacters*sizeof(TCHAR))
7.尽量避免使用printf系列的函数,尤其是有%s,%S字段类型来进行ANSI和Unicode字符串之间的相互转换。正确的做法是使用MultiByteToWideChar和WideCharToMultiByte函数
8.对于UNICODE和_UNICODE,要么都定义,要么都不要用,因为VS会在我们创建项目的时候默认定义_UNICODE。
9.使用安全的字符串函数,如后缀为_s的函数或是前缀为StringCch的函数,后者会截断字符串。前者需指定字符串长度。
10.使用/GS 和/RTCS编译器选项来自动检测缓冲区溢出。
使用UNICODE编码规范是一种好的编程习惯,但是,有的时候,我们不得不使用ANSI编码方式,这种情况该如何处理呢?
请看下集UNICODE和ANSI字符串的转换
同系列文章参看:
《 让你的程序更加适用——使用ANSI和UNICODE导出函数 》
http://blog.csdn.net/blpluto/article/details/5755162
多字符集(ANSI)和UNICODE及字符串处理方式准则的更多相关文章
- 有关UNICODE、ANSI字符集和相关字符串操作
Q UNICODE字符串如何显示 A 如果程序定义了_UNICODE宏直接用 WCHAR *str=L"unicodestring"; TextOut(0,0,str); 否则就需 ...
- 《windows核心编程系列》二谈谈ANSI和Unicode字符集 .
http://blog.csdn.net/ithzhang/article/details/7916732转载请注明出处!! 第二章:字符和字符串处理 使用vc编程时项目-->属性-->常 ...
- Ansi 与 Unicode 字符串类型的互相转换
WideCharToMultiByte 实现宽字节转换到窄字节MultiByteToWideChar 实现窄字节转换到宽字节 WideCharToMultiByte 的代码页用来标记与新转换的字符串相 ...
- Ansi、Unicode、UTF8字符串之间的转换和写入文本文件
转载请注明出处http://www.cppblog.com/greatws/archive/2008/08/31/60546.html 最近有人问我关于这个的问题,就此写一篇blog Ansi字符串我 ...
- unicode,ansi,utf-8,unicode big endian编码的区别
知乎--http://www.zhihu.com/question/23374078 http://wenku.baidu.com/view/cb9fe505cc17552707220865.html ...
- Ansi,UTF8,Unicode,ASCII编码的差别
近日须要不同的编码,关于上述编码,一直迷迷糊糊,查了些资料,总算大致了解了,以下全是从网上搜来的: 1. ASCII和Ansi编码 字符内码(charcter code)指的是用来代表字符的内 ...
- ANSI与Unicode的转换
最近遇到中文路径访问的问题,又重新学习了一遍ansi与Unicode的知识,博文记录下来以供后续参考. ANSI 编码 ANSI是一种字符代码,为使计算机支持更多语 言,通常使用0x80~0xFF 范 ...
- Ansi,UTF8,Unicode,ASCII编码的区别 ---我看完了 明白了很多
来自:http://blog.csdn.net/xiongxiao/article/details/3741731 ------------------------------------------ ...
- Ansi,UTF8,Unicode,ASCII编码的区别
Ansi,UTF8,Unicode,ASCII编码的区别 近日需要不同的编码,关于上述编码,一直迷迷糊糊,查了些资料,总算大致了解了, 下面全是从网上搜来的: 1. ASCII和Ansi编码 ...
随机推荐
- zookeeper 之znode 节点
<pre name="code" class="html">使用 ls 命令来查看当前 ZooKeeper 中所包含的内容: [zk: 10.77. ...
- C++学习笔记(十二):重载函数
1. 什么是重载函数 假设同一作用域内的几个函数名字同样但形參列表不同.那么这些函数就称之为--重载函数. 比如: void print( const char *cp); void print(co ...
- 使Web Api 支持跨域资源共享(CORS)
Reference:http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api Imp ...
- 遭遇“HTTP 错误 500.19 无法访问请求的页面,因为该页的相关配置数据无效。”
windows 2008下IIS7 安装ASP.NET 遇到如下错误: HTTP 错误 500.19 - Internal Server Error 无法访问请求的页面,因为该页的相关配置数据无效. ...
- delphi高手突破学习笔记之面向对象类和对象的本质(有汇编解释 good)
知识点1:堆和栈 每个应用程序可以获得的内存空间分为两种:堆(heap)和栈(stack). 堆又称为“自由存储区”,其中的内存空间的分配与释放是必须由程序员来控制的.例如,用GetMem函数获取了一 ...
- Project configuration is not up-to-date with pom.xml错误解决方法
导入一个Maven项目之后发现有一个如下的错误: Project configuration is not up-to-date with pom.xml. Run project configura ...
- debian网易163更新服务器 源
sudo vi /etc/apt/sources.list 加入如下内容即可: deb http://mirrors.163.com/debian/ jessie main non-free cont ...
- Caffe —— Deep learning in Practice
因工作交接须要. 要将caffe用法及总体结构描写叙述清楚. 鉴于也有同学问过我相关内容, 决定在本文中写个简单的tutorial, 方便大家參考. 本文简单的讲几个事情: Caffe能做什么? 为什 ...
- 【linux】linux启动流程
欢迎转载,转载时请保留作者信息,谢谢. 邮箱:tangzhongp@163.com 博客园地址:http://www.cnblogs.com/embedded-tzp Csdn博客地址:http:// ...
- Javascript跨域请求的几种解决方法
什么情况下才会出现跨域? 假设域名是:http://www.example.com.cn/ 如果所请求的域名跟这个域名不致,这种情况就是跨域,由于跨域存在漏洞,所以一般来说正常的跨域请求方式是请求不到 ...