多字符集(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编码 ...
随机推荐
- BZOJ 1009: [HNOI2008]GT考试( dp + 矩阵快速幂 + kmp )
写了一个早上...就因为把长度为m的也算进去了... dp(i, j)表示准考证号前i个字符匹配了不吉利数字前j个的方案数. kmp预处理, 然后对于j进行枚举, 对数字0~9也枚举算出f(i, j) ...
- redis安装及数据类型简介(string、list、set、sorted_set、hash)
一:简介: redis国内最大的案例--->新浪微博 memcache:是key-value数据库 数据类型:只支持key value数据 过期策略:支持 持久化:不支持(可以通过三方程序) 主 ...
- 我的Python成长之路---第二天---Python基础(8)---2016年1月9日(晴)
数据类型之字典 一.字典简介 字典dict(dictionary),在其他语言中也成为map,使用键-值(key-value)的形式存储和展现,具有极快的查找速度. 字典的定义 d = {'key': ...
- MySQL主键添加/删除
2改动数据库和表的字符集alter database maildb default character set utf8;//改动数据库的字符集alter table mailtable defaul ...
- []: secureCRT连接ubuntu问题- The remote system refused the connection
secureCRT连接ubuntu问题- The remote system refused the connection http://jxyang.iteye.com/blog/1484915 解 ...
- perl $d = encode_utf8($r); $f = decode_json($d)
[root@dr-mysql01 ~]# cat a1.pl my $url="http://192.168.32.101:3000/api/getcode?env=zj&phone ...
- 基于visual Studio2013解决C语言竞赛题之1027 YN
题目 解决代码及点评 /* 计算Yn的值,直到|Yn - Yn-1|<10-6为止,并打印出此时共作了多少次COS计算. 提示:Yn+1=COS(Yn),故本 ...
- UVA 322 ships (POJ 1138)
题目地址: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- Swift - final关键字的介绍,以及使用场景
final关键字在大多数的编程语言中都存在,表示不允许对其修饰的内容进行继承或者重新操作.Swift中,final关键字可以在class.func和var前修饰. 通常大家都认为使用final可以更好 ...
- EasyUI - DataGrid 组建 - [ 样式功能 ]
效果显示: 同上次博文效果. html代码: 同上次博文代码. js代码: align: 'center',//标题和内容居中 resizable: false,//不允许改变大小 //hidden: ...