• 多字符集(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

  • 相关阅读:
    如何节省 1TB 图片带宽?解密极致图像压缩
    微信亿级用户异常检测框架的设计与实践
    一文带你深度解析腾讯云直播答题方案
    kafka数据迁移实践
    揭密微信跳一跳小游戏那些外挂
    从蓝光到4K,腾讯视频高码率下载背后的技术
    GridControl列自动匹配宽度
    access的逻辑类型
    NPOI Excel类
    Access sql语句创建表及字段类型
  • 原文地址:https://www.cnblogs.com/findumars/p/5290226.html
Copyright © 2020-2023  润新知