多字符集(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编码 ...
随机推荐
- django局域网建一个网站
之前总是运行的python manage.py runserver,用默认的在本机访问的127.0.0.1:8000,如果跟几个同学一起去开发一个网站来玩玩的话,可以这样: python manage ...
- Qt核心剖析: moc
前面我们说过,Qt 不是使用的“标准的” C++ 语言,而是对其进行了一定程度的“扩展”.这里我们从Qt新增加的关键字就可以看出来:signals.slots 或者 emit.所以有人会觉得 Qt 的 ...
- 欢迎大家关注我的微信公众帐号小q机器人(xiaoqrobot)(转)
一个偶然的机会让我接触到了微信公众平台,赶紧加了几个交流群了解下相关情况,突然间发现好像全部的APP开发人员都在研究微信公众帐号的开发,而我显得有些落舞了.至于为什么热度会这么高,我想一个数字足以说明 ...
- Flexigrid的编辑功能
editCells:function(){ if(!isEditing){ isEditing = true; $('tbody tr',$(t)).each(function () { for(va ...
- Javascript面向对象研究心得
这段时间正好公司项目须要,须要改动fullcalendar日历插件,有机会深入插件源代码.正好利用这个机会,我也大致学习了下面JS的面向对象编程,感觉收获还是比較多的. 所以写了以下这篇文章希望跟大家 ...
- 全陷阱破解:在Linux环境下的Jenkins中持续集成Androidproject
本方案以 RHEL / Centos 64位Linux操作系统为例,由于这是眼下最常见的server环境. 一.安装Java SDK. 建议,不要使用诸如yum之类的玩意自己主动安装,由于openJD ...
- Linux下安装配置词典GoldenDict
GoldenDict apt-get install goldendict 安装完成以后,需要自己手动加入字典,增加在线翻译网址(例如,有道,金山等),点击 编辑--dictionaries 完 ...
- perl use utf8
utf8 Perl编译 来启用/禁用 UTF-8(or UTF-EBCDIC) 在源代码里 简洁: use utf8; no utf8; # Convert the internal represen ...
- 南京三星面试准备3--数组&基础数据结构
1.用递归颠倒一个栈. void PushToBottom(stack<int> &mystack,int num) { if(mystack.size()==0) { mysta ...
- VC++笔记七
动态链接库修改文件名问题? eg:GetRadarFS.dll->RadarModel.dll; 注意修改:打开文件GetRadarFs.def 修改 LIBRARY "GetRad ...