多字符集(ANSI)和UNICODE及字符串处理方式准则

在我们编写程序的时候,使用最多的是字符串的处理,而ANSI和UNICODE的相互转换经常搞的我们头晕眼乱。

应该说UNICODE是一种比较好的编码方式,在我们的程序中应该尽量使用UNICODE编码方式,我们在编写程序的时候,最好能依据下面的准则来进行:

基本准则:

1.将文本字符串想象为字符数组,而非char或字节数组

2.开始使用通用数据类型来表示文本字符和字符串(如TCHAR,PTSTR)

原因是我们可以在WinNT.h的头文件中找到如下定义(代码有删改):

[cpp] view plain copy

  1. #ifndef VOID
  2. #define VOID void
  3. typedef char CHAR;
  4. typedef short SHORT;
  5. typedef long LONG;
  6. typedef int INT;
  7. #endif
  8. #endif
  9. //
  10. // UNICODE (Wide Character) types
  11. //
  12. #ifndef _MAC
  13. typedef wchar_t WCHAR;    // wc,   16-bit UNICODE character
  14. #else
  15. // some Macintosh compilers don‘t define wchar_t in a convenient location, or define it as a char
  16. typedef unsigned short WCHAR;    // wc,   16-bit UNICODE character
  17. #endif
  18. typedef  WCHAR *PWCHAR, *LPWCH, *PWCH;
  19. typedef  CONST WCHAR *LPCWCH, *PCWCH;
  20. typedef  WCHAR *NWPSTR, *LPWSTR, *PWSTR;
  21. typedef  PWSTR *PZPWSTR;
  22. typedef  CONST PWSTR *PCZPWSTR;
  23. typedef  WCHAR UNALIGNED *LPUWSTR, *PUWSTR;
  24. typedef  CONST WCHAR *LPCWSTR, *PCWSTR;
  25. typedef  PCWSTR *PZPCWSTR;
  26. typedef  CONST WCHAR UNALIGNED *LPCUWSTR, *PCUWSTR;
  27. typedef CONST WCHAR *LPCWCHAR, *PCWCHAR;
  28. typedef CONST WCHAR UNALIGNED *LPCUWCHAR, *PCUWCHAR;
  29. //
  30. //  UCS (Universal Character Set) types
  31. //
  32. typedef unsigned long UCSCHAR;
  33. #define UCSCHAR_INVALID_CHARACTER (0xffffffff)
  34. #define MIN_UCSCHAR (0)
  35. //
  36. // ANSI (Multi-byte Character) types
  37. //
  38. typedef CHAR *PCHAR, *LPCH, *PCH;
  39. typedef CONST CHAR *LPCCH, *PCCH;
  40. typedef  CHAR *NPSTR, *LPSTR, *PSTR;
  41. typedef  PSTR *PZPSTR;
  42. typedef  CONST PSTR *PCZPSTR;
  43. typedef  CONST CHAR *LPCSTR, *PCSTR;
  44. typedef  PCSTR *PZPCSTR;
  45. //
  46. // Neutral ANSI/UNICODE types and macros
  47. //
  48. #ifdef  UNICODE                     // r_winnt
  49. #ifndef _TCHAR_DEFINED
  50. typedef WCHAR TCHAR, *PTCHAR;
  51. typedef WCHAR TBYTE , *PTBYTE ;
  52. #define _TCHAR_DEFINED
  53. #endif /* !_TCHAR_DEFINED */
  54. typedef LPWCH LPTCH, PTCH;
  55. typedef LPWSTR PTSTR, LPTSTR;
  56. typedef LPCWSTR PCTSTR, LPCTSTR;
  57. typedef LPUWSTR PUTSTR, LPUTSTR;
  58. typedef LPCUWSTR PCUTSTR, LPCUTSTR;
  59. typedef LPWSTR LP;
  60. #define __TEXT(quote) L##quote      // r_winnt
  61. #else   /* UNICODE */               // r_winnt
  62. #ifndef _TCHAR_DEFINED
  63. typedef char TCHAR, *PTCHAR;
  64. typedef unsigned char TBYTE , *PTBYTE ;
  65. #define _TCHAR_DEFINED
  66. #endif /* !_TCHAR_DEFINED */
  67. typedef LPCH LPTCH, PTCH;
  68. typedef LPSTR PTSTR, LPTSTR, PUTSTR, LPUTSTR;
  69. typedef LPCSTR PCTSTR, LPCTSTR, PCUTSTR, LPCUTSTR;
  70. #define __TEXT(quote) quote         // r_winnt
  71. #endif /* UNICODE */                // r_winnt

3.用明确的数据类型来表示字节,字节指针和数据缓冲区(如BYTE, PBYTE)原因如上同

4.使用TEXT或是_T来表示字面量字符和字符串(这两个宏会根据你自己设置的字符集属性,动态转换成相应的字符集)

5.执行全局替换,原因同2.

6.修改与字符串有关的计算。如有些函数需要我们传入缓冲区大小的字符数,这个时候就需要_countof(szBuffer),而不是sizeof(szBuffer);

有些时候我们需要为一个字符串分配内存,那么内存是使用字节数来分配的,这个时候我们就需要使用malloc(nCharacters*sizeof(TCHAR)),而不是使用malloc(nCharacters).

我们可以使用如下样式的宏来处理这个问题:

[c-sharp] view plain copy

  1. #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字符串的转换

同系列文章参看:

 UNICODE和ANSI字符串的转换  

 

《 让你的程序更加适用——使用ANSI和UNICODE导出函数 》

http://blog.csdn.net/blpluto/article/details/5755162

时间: 2024-08-28 18:28:12

多字符集(ANSI)和UNICODE及字符串处理方式准则的相关文章

Ansi 与 Unicode 字符串类型的互相转换

WideCharToMultiByte 实现宽字节转换到窄字节MultiByteToWideChar 实现窄字节转换到宽字节 WideCharToMultiByte 的代码页用来标记与新转换的字符串相关的代码页:MultiByteToWideChar 的代码页用来标记与一个多字节字符串相关的代码页, [1].常用的代码页有 CP_ACP 和 CP_UTF8 两个: 使用 CP_ACP 代码页就实现了 ANSI 与 Unicode 之间的转换:--- 我们所用的!使用 CP_UTF8 代码页就实现

ANSI与Unicode的转换

最近遇到中文路径访问的问题,又重新学习了一遍ansi与Unicode的知识,博文记录下来以供后续参考. ANSI 编码 ANSI是一种字符代码,为使计算机支持更多语 言,通常使用0x80~0xFF 范围的2 个字节来表示1 个字符.不同的国家和地区制定了不同的标准,由此产生了GB2312.GBK.GB18030.Big5.Shift_JIS 等各自的编码标准. 这些使用多个字节来代表一个字符的各种汉字延伸编码方式,称为ANSI 编码. 关于MBCS字符集(Multi Byte Character

Ansi,UTF8,Unicode,ASCII编码的差别

近日须要不同的编码,关于上述编码,一直迷迷糊糊,查了些资料,总算大致了解了,以下全是从网上搜来的: 1.  ASCII和Ansi编码    字符内码(charcter code)指的是用来代表字符的内码.读者在输入和存储文档时都要使用内码,内码分为     单字节内码 -- Single-Byte character sets (SBCS),能够支持256个字符编码.     双字节内码 -- Double-Byte character sets)(DBCS),能够支持65000个字符编码.前者

Ansi,UTF8,Unicode,ASCII编码的区别 ---我看完了 明白了很多

来自:http://blog.csdn.net/xiongxiao/article/details/3741731 ------------------------------------------------------------------------ 近日需要不同的编码,关于上述编码,一直迷迷糊糊,查了些资料,总算大致了解了,下面全是从网上搜来的: 1.  ASCII和Ansi编码    字符内码(charcter code)指的是用来代表字符的内码.读者在输入和存储文档时都要使用内码

ANSI与Unicode编码,TCHAR | LPSTR | LPCSTR | LPWSTR | LPCWSTR | LPTSTR | LPCTSTR 的含义

一个字符可以用1-byte表示,即ANSI编码: 一个字符也可用2-bytes表示,即Unicode编码(Unicode其实还包含了更多内容,不止2-bytes). Visual C++支持char和wchar_t作为ANSI和Unicode的原始数据类型. 例如 char cResponse; // 'Y' or 'N' char sUsername[64]; // str* functions 以及 wchar_t cResponse; // 'Y' or 'N' wchar_t sUser

ASCII、ANSI、Unicode编码

3.1 ASCII编码 以下来自"维基百科": ASCII(American Standard Code for Information Interchange,美国信息互换标准代码)是基于拉丁字母的一套电脑编码系统.它主要用于显示现代英语,而其扩展版本EASCII则可以勉强显示其他西欧语言.它是现今最通用的单字节编码系统(但是有被UniCode追上的迹象),并等同于国际标准ISO/IEC 646. ASCII第一次以规范标准的型态发表是在1967年,最后一次更新则是在1986年,至今

Visual C++一定要注意ANSI和UNICODE的区别

最近在学习VC++,下载了VS2013,照着<Visual C++开发实战宝典>的第一个hello例程写了个例子,结果出现编辑框乱码的问题.晚上一直在折腾类型的转化,后来总结才明白了是ANSI和UNICODE的区别.老教程刚出的时候,这些控件接口都是ANSI的格式,而现在都统一成了UNICODE了. void ChelloDlg::OnBnClickedOk() { CString csPlus; //定义字符串变量 CString csSummand; m_PlusNumber.GetWin

关于ASCII、GB231、GBK、UTF-8/UTF8、ANSI、unicode的学习笔记

继续上次的学习内容,写一些自己学习的笔记吧!总是觉得没有笔记的学习总是不那么踏实,我承认自己是个记忆力很差的人,特别羡慕那些可以把自己学过的东西记得很牢靠的人.哎!可惜我不是,那只能做出来点东西,就算以后忘了,回过头来可以看一看,有东西查:毕竟是自己亲手打出来的一个一个字啊 已经一万六千字了!嘿嘿...继续加油! 今天公司网络有问题,说是让在家里上班,skype在线就行了.结果我这自觉性不够,就打酱油了!还是继续学习我的mysql吧!我是刚毕业的大学生,学的和写的都是一些最基础的,如果巧遇大牛,

ANSI和UNICODE编程的注意事项

建立UNICODE编码工程 在VC60下,默认方式下建立的是ANSI编码的工程(注:编译的exe内部,其资源字符是以UNICODE保存),建立UNICODE编码工程的方法: 1.为工程添加UNICODE和_UNICODE预处理选项.   具体步骤:打开[工程]->[设置-]对话框,在C/C++标签对话框的"预处理程序定义"中去除_MBCS,加上_UNICODE,UNICODE.(注意中间用逗号隔开). 在没有定义UNICODE和_UNICODE前,所有函数和类型都默认使用ANSI