字符集之代码书写和底层探索
代码书写注意事项:
1.用字符串常量构造字符串对象时,std::wstring时用宏L;构造CString和别的随配置可变字宽类型对象时用宏_T;
2.用系统函数时要选用可随系统配置变化的API如:::GetDirect(),并传入可变字宽的字符串对象如LPCTSTR,
不提昌用::GetDirectA()或::GetDirectW()这样被定死的;
3.当需要外来参数向本地代码参数传值或相反情况时,如果其中一个参数是可随配置变化的,另一个是定死的,此时
建议用宏把代码区分开:#ifdef _UNICODE
m_img = new Gdiplus::Image(szFilename,FALSE);
#else
m_img = new Gdiplus::Image(A2W(szFilename), FALSE);
#endif
4.构造CString类对象时,要用_T,不然虽能编过(内部转换),CString("古月方")即使以UNICODE编译的在非本地语言机子上显示还是乱码。
我是比较喜爱CString的高效易用和灵活性的。它内部的引用计数机制和随配置字宽可变性是很好的。
5.替换常用的正则表达式:
_T\({"[^"]*"}\)
L\1
MessageBox\(L{"[^"]*"}
MessageBox(_T(\1)
MessageBox\({[^,]*},L{"[^"]*"}
MessageBox(\1,_T(\2)
MessageBox\({[^,]*}, {[^,]*}, L{"[^"]*"}
MessageBox(\1, \2, _T(\3)
C 语言原本是在英文环境中设计的,主要的字符集是7 位的ASCII 码。从此开始,8 位的byte(字节)变成最常见的字符编码单位,但是国际化软件必须能够表示不同的字符,ISO C 可以标准化两种表示大型字符集的方法:宽字符(wide character,该字符集内每个字符使用相同的位长)以及多字节字符(multibyte character,每个字符可以是一到多个字节不等,而某个字节序列的字符值由字符串或流(stream)所在的环境背景决定)。
注意:虽然C现在提供抽象机制,可以处理和转换不同种类的编码集合,但语言本身并没有定义或指定任何编码集合,或任何字符集(除基本源代码字符集和基本运行字符集外)。换句话说,这部分是由个别的实现版本指定如何编码宽字符,以及要支持什么类型的多字节字符编码机制。
自从1994 年的增补之后,C 不只提供char类型,还提供wchar_t类型(宽字符),此类型定义在stddef.h 头文件中。wchar_t 类型足以表示某个实现版本扩展字符集的任何元素。虽然C 标准没有支持Unicode 字符集,许多实现版本使用Unicode 转换格式UTF-16 和UTF-32来处理宽字符。
C 提供了一些标准函数,可以将多字节字符转换为wchar_t,或将宽字符转换为多字节字符。比方说,如果C 编译器使用Unicode 标准的UTF-16 和UTF-8,下面函数就可以获得字符的多字节表示方式(注:wctomb = WideCharToMultiByte())。
C++的中英文字符串默示(string,wstring),字符串类的模板原型是basic_string
string完全可以存储中文(有效编码只有""\0""=0,其他字符均不为0),然则在显示、字符操纵等方面是无法包管正确的!
前者string是常用类型,可以看作char[],其实这恰是与string定义中的_Elem=char相一致。而wstring,应用的是wchar_t类型,这是宽字符,用于满足非ASCII字符的请求,例如Unicode编码,中文,日文,韩文什么的。对于wchar_t类型,实际上C++中都用与char函数相对应的wchar_t的函数,因为他们都是从同一个模板类似于上方的体式格式定义的。是以也有wcout,wcin,werr等函数。实际上string也可以应用中文,然则它将一个汉字写在2个char中,但有些函数操作出错。而若是将一个汉字看作一个单位wchar_t的话,那么在wstring中就只占用一个单位,其它的非英文文字和编码也是如此。如许才真正的满足字符串操纵的请求,尤其是国际化等工作。
(CSDN资料)VS2010中字符集配置:定义是否应该设置 _UNICODE 或 _MBCS。在适当的地方还影响链接器入口点。
可以通过用字母 L 作为字符的前缀将任何 ASCII 字符表示为宽字符形式。例如,L'\0' 是宽(16 位)NULL 字符。同样,可以通过用字母 L 作为 ASCII 字符串的前缀 (L"Hello") 将任何 ASCII 字符串表示为宽字符字符串形式。
C 运行时库有两类内部代码页:区域设置和多字节。在程序执行期间可以更改当前代码页(有关 setlocale 和 _setmbcp 函数的信息,请参见文档)。而且,运行时库可以获取并使用操作系统代码页的值。在 Windows 2000 中,操作系统代码页是“系统默认 ANSI”代码页。此代码页在程序的执行期间保持不变。
内码是指操作系统内部的字符编码。早期操作系统的内码是与语言相关的使用7位的ASCII编码。为了处理汉字,程序员设计了用于简体中文的Windows内码GBK。目前Windows的内核已经支持Unicode字符集,然后用代码页适应各种语言,“内码”的概念就比较模糊了。微软一般将缺省代码页指定的编码说成是内码,即缺省用什么编码来解释字符。例如Windows的记事本打开了一个文本文件,里面的内容是字节流:BA、BA、D7、D6。Windows应该去怎么解释它呢?是按照Unicode编码解释、还是按照GBK解释?
答案是Windows按照当前的缺省代码页去解释文本文件里的字节流。缺省代码页可以通过控制面板的区域选项设置。记事本的另存为中有一项ANSI,其实就是按照缺省代码页的编码方法保存。
Windows的内码是Unicode,它在技术上可以同时支持多个代码页。只要文件能说明自己使用什么编码,用户又安装了对应的代码页,Windows就能正确显示。Unicode也是一种字符编码方法,不过它是由国际组织设计,可以容纳全世界所有语言文字的编码方案。
Unicode最早的编码想法,就是把每一个码点(code point)都存储在两个字节中,这也就导致了大多数人的误解,于是非常聪明的UTF-8的概念被引入了,用来存储字符串所对应的Unicode的码点。
UTF-8就是以8位为单元对UCS(Unicode字符集)进行编码。
读者可以用记事本测试一下我们的编码是否正确。需要注意,UltraEdit在打开utf-8编码的文本文件时会自动转换为UTF-16,可能产生混淆。你可以在设置中关掉这个选项。更好的工具是Hex Workshop。
C语言中,字符(character)这个术语具有两个层次上的含义:书写源程序的字符和程序处理的字符。
例如,printf("你好,C!\n"); 之内的“你好\n”就属于程序要处理的字符。
从某种意义上来说,编辑/编译器是一种接受字符输入,输出可执行文件的软件,由它产生可执行文件经过加载成为内存中的程序,这个程序通常也不可避免地要处理字符。
编辑/编译器所要处理的字符就是书写C语言源程序所用的字符,这种字符的集合叫源字符集(sourcecharacter set)。而应用程序要处理的字符所构成的集合叫执行字符集(execution character set)。这两者又不同于编码时的字符集及其配置的概念。
摘自 hlfkyo的专栏
补充:软件开发 , C语言 ,