关于国际化与字符编码(乱码)大家相关的内容也可以放啊

超级管理员9527 2007-03-25 08:56:17
[原crybird]
本文纯属个人观点,很多问题还没看到问题的本质,请各位高手、大牛指教。
本文概念基于VC++和Windows。
部分素材来源网络,如有侵权,请联系me :)
允许非商业目的转载,如有转载,请标明[转]字。

第一部分:国际化

一什么是ID
简单的说,ID本质是一个整数,在不同的场合,具有不同的意义。主要是用来区分群体中的个体,即把群体中的某个个体,抽象成一个整数,在一定范围内使用和识别。

二LocalID
如何在世界的众多区域中标识本地区域呢?用LocalID,它是在语言的基础上抽象的一种标识。LocalID是由两个id拼接而成的,LanguageID和SortID。
DWORD MAKELCID(WORD lgid, WORD srtid)

三LanguageID
LanguageID也是由两个id拼接而成的,主id和子id。以简体中文为例,此外还要其他语言的主id,和台湾香港澳门等相关的子id。
WORD MAKELANGID(WORD priID, WORD subID)
#define LANG_CHINESE 0x04
#define SUBLANG_CHINESE_SIMPLIFIED 0x02
宏处理后,简体中文是0x804

四SortID
#define SORT_CHINESE_PRC 0x2 // PRC Chinese Stroke Count order

相关宏有:
MAKELCID
LANGIDFROMLCID
SORTIDFROMLCID
MAKELANGID
SUBLANGID
PRIMARYLANGID
LocalID、LanguageID、SorID的相关宏和预定义的值,请参阅包含在winnt.h,也可查阅MSDN。
...全文
1143 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
a9832566444 2012-08-17
  • 打赏
  • 举报
回复
很好的一个帖子
楼主有心了
ASCII码中 一个英文字母占一个字节的空间
一个中文汉字占两个字节的空间
英文标点占一个字节
中文标点占两个字节
UNICODE码中 每个字符都占两个字节
Unicode有着统一的标准,它定义了世界上绝大多数的字符的编码(encoding)
使得拉丁文、数字、简体中文、繁体中文、日文等都可以同一种编码方式保存
yc_8301 2007-09-12
  • 打赏
  • 举报
回复
学习。。。。
ToperRay 2007-03-29
  • 打赏
  • 举报
回复
学习~~
xyxfly 2007-03-29
  • 打赏
  • 举报
回复
学习~-~
  • 打赏
  • 举报
回复
大家有什么想法,发表一下。以后可以总结一个总的,不会再为这些麻烦的概念所困扰

...

***这里说的只是概念上的东西,并不是技术细节***
***如有差错,请指出,并请谅解***
  • 打赏
  • 举报
回复
故事开始了。。。在很久很久以前。。。久以前。。。久以前。。。以前。。。以前。。。
永远记住,计算机只认识0和1。梦魇开始了。。。
人类把符号映射成整数,让计算机去处理。最开始的时候,计算机里用一个字节表示所有字符,包括字母、数字和一些符号。最高位置0,所以共包含128个字符。这些定义好的字符组成了ASCI表。后来发现128个字符不够用了,就把最高位也用上了,共包含256个字符,这些字符组成了扩展ASCI表。
与此同时,中国等一些亚州国家的字符远不止256个,一个字节是不足以表示这些字符的博大精深的。所以,就采用2个字节表示一个字符,同时兼容ASCI。于是GB2312标准字符集产生了,后来又扩展到了GBK,并兼容了香港和台湾的繁体。用两个字节表示一个符号,就是所谓的DBCS(double-byte CharSet)。但是,两个字节最多也仅能容65536个字符,虽然已经足够一般情况用了,可特殊的情况(特殊符号、生僻字等等)总是让人讨厌。而且中国大陆、台湾繁体、韩日等等国家的字符集都是独立定义的,同样两个字节,中文的简体和繁体就可能代表不同的汉字,当进行国际交流的时候,乱码肆虐的时刻来临了。。。
地球村是越来越小的,有必要让所有村民使用的字符互不干扰,统一成一个公共的字符集。于是Unicode应运走进历史的舞台。用两个字节代表一个符号,而且兼容ASCI表。为了容易数,规定两个字节等于一个宽字符,这样符号的个数和宽字符的个数就一直了。这就是UCS-2。事实证明,他们低估了中国汉字的数量,65535个位置全分配给中国还不够呢,于是又出现了用四个字节表示一个字符的UCS-4。现在把世界上所有语言的符号包进去,都放的下了。(现在最常用的,还是UCS-2)
不过,没有什么是完美的。Unicode在传输的时候总是有意想不到的差错。还好人类聪明,把Unicode编码改成用不定个字节表示一个符号,可能是一个、两个、甚至六个。这样用来传输是很方便的。于是UTF8、UTF16产生了。这样用多个字节表示一个字符,就是所谓的多字节字符集MBCS(Multi-byte CharSet)。
  • 打赏
  • 举报
回复
先看一些令人头疼的概念:字符集CharSet、代码页CodePage、编码Encoding、字体Font、ASCI、UNICODE、双字节字符集DBCS、多字节字符集MBCS、GB2312、GBK、UTF8...
syy64 2007-03-28
  • 打赏
  • 举报
回复
mark
oliverlin 2007-03-28
  • 打赏
  • 举报
回复
向LZ学习。。。
cloudgamer 2007-03-26
  • 打赏
  • 举报
回复
编码
man28 2007-03-25
  • 打赏
  • 举报
回复
最近正苦恼一件汉化的事,请各位指教:
在汉化一个unicode编码的大英文软件时,出现两个问题:
一是有些地方出现乱码,
二是有几个string table里的条目翻译后运行时点击程序出现崩掉现象
程序有原代码,c++语言写的,我在vc++6.0下打开资源,把属性设置成中文后(我的系统和vc++都是英文版)开始翻译成中文,菜单翻译后运行正常,翻译几个string table里的条目运行出问题,请高手和有汉化经验的朋友指点!!!谢谢
hujun614 2007-03-25
  • 打赏
  • 举报
回复
显示汉字的时候,反正只要编码不对,就肯定乱码,这是必然的。

不过UTF-8的标准英文字符在ANSI字符集,GB2312的字符集的显示方式下都是正确的!
hujun614 2007-03-25
  • 打赏
  • 举报
回复
向楼主学习,接分(楼主的分多啊,呵呵)!!!
  • 打赏
  • 举报
回复
第二部分:字符编码

一CharSet(字符集):
字符集(CharSet或者character repertoire)是一组抽象字符(abstract character)的集合,这里的字符是用来表达语义的符号。比如所有汉字构成的字符集,西欧语言字母构成的字符集,符号构成的字符集等。字符集的子集也为字符集,比如所有繁体字的集合。下面是一些字符集的ID,
#define ANSI_CHARSET 0 (ASCI)
#define GB2312_CHARSET 134 (中简GB2312)
#define CHINESEBIG5_CHARSET 136 (中繁BIG5)
#define SHIFTJIS_CHARSET 128 (日)
#define HANGUL_CHARSET 129 (韩)
此外还有阿拉伯、希腊等等。

二CodePage(代码页):
以简体中文为例子,为了计算机查找排序方便,给所有的简体中文和一些符号(按一定的规律和规则)映射一个整数表,表里面的每一个整数对应一个汉字或符号,这个表就是代码页。(这里的整数不约束于四个字节)。
具体的说,一个字节能表示的范围是0-127,而字符却成千上万个。由于字符个数大大多于一个字节能表示的范围,所以一般用多个字节表示一个字符。(这里的多个字节对应上段内容的整数,定义为“字节串”概念)
字符集和代码页不一定是一一对应的关系,字符集里面的字符和代码页中的整数也不一定是一一对应的。比如代码页A中可以对应字符集1的中文简体中文和字符集2的英文字母。而代码页B中可以对应所有的简体和繁体中文。
#define CP_ACP 0 // default to ANSI code page
#define CP_OEMCP 1 // default to OEM code page
#define CP_MACCP 2 // default to MAC code page
#define CP_THREAD_ACP 3 // current thread's ANSI code page
#define CP_SYMBOL 42 // SYMBOL translations
#define CP_UTF7 65000 // UTF-7 translation
#define CP_UTF8 65001 // UTF-8 translation
可以在控制面板-区域和语言中查看自己电脑中安装的CodePage。

三什么是编码Encoding
说明CodePage的时候,所谓的“一定的规律和规则”就是编码。编码的结果就是代码页。
当前国际上最为通用的字符编码(商业规范)是Unicode编码。Unicode是由一个非赢利性组织“Unicode学术学会”建立和发展的涵盖世界大多数流行语言的字符编码形式。Unicode[现有的标准]版本为4.1,其中包含的所有语言符号(超过9万个,其中汉字为7万多)。
其他编码:GB2312, GB13000, GB18030, Unicode,UTF-8这些都是对字符集的编码(encoding)。其中常见对汉语字符集的编码包括GB2312-1980, GB13000, GBK, GB12345, GB18030—2000, Big5, Big5+, HKSCS, Big5+HKSCS, CNS 11643-1992等。UCS-2, UCS-4, UTF-32, UTF-16, UTF-8, UTF-EBCDIC和UTF-7都是Unicode编码的具体形式(即它们不是直接映射的字符,而是映射的Unicode码,其实也就对应字符啦)。

四多字节编码
由于字符个数大大多余一个字节能表示的范围,所以一般用多个字节表示一个字符。还以汉字为例子,一个汉字,在这个代码表中用1234表示,在另外一个代码表中可能用56789表示,如何转换呢?先把1234转换成一个标准的编码,然后由标准的编码转换成56789,
如此转换可以减少转换复杂度。这个“标准”就是上面提到的Unicode。同时用到了以下两个转换的window API:
MultiByteToWideChar(...)
WideCharToMultiByte(...)

五字体(Font)
知道“宋体”和“黑体”的区别,就不用解释字体的意义了。
要注意的是,字体不支持所有的字符。比如说宋体不会支持阿拉伯和梵文。所以要生成字体的时候,要选择字符集。字体里面存的是下笔拐弯和画直线等信息,对应的是文字符号。

六乱码的产生和消除
乱码产生的原因可能原因有:1代码页转换问题2没有应用合适的字体。大多数乱码出现是由于第一个原因,这里只介绍原因1。
还是拿汉字为例子。比如一个汉字,目前表示对应的是UTF-8编码中的12345。而默认的PageCode是GB2312。当显示汉字的时候,在GB2312中找12345对应的文字,肯定是错误的字或者乱码。如何正确显示呢?首先用MultiByteToWideChar函数把UTF-8编码转换成Unicode编码,再用WideCharToMultiByte函数把Unicode编码转换成GB2312的编码,然后显示才会正确。如下:
UTF-8 ---- 12345
Unicode ---- 55555
GB2312 ---- 98765
当显示的时候,在GB2312中找98765就会找到UTF-8中12345对应的汉字了。当然,用阿拉伯文字体或者梵文字体还是显示不出正确的字,还是找宋体吧 :)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧