• 多字节字符与宽字符


    背景知识

    字符是人们认识世界,用来标记的符号。但是计算机并不认识这些字符。
    所以需要对这些字符进行编号,这样,字符与编码之间就形成了映射关系。当你输入65的时候,计算机才能识别,你其实想表达的是'A'.

    常见的字符集:ANSI字符体系,Unicode字符体系
    ANSI体系:ASCII字符集、GB2312字符集(主要用于处理中文汉字)、GBK字符集(主要用于处理中文汉字)
    Unicode体系:Unicode字符集

    编码:
    ASCII字符集----ASCII编码
    GB2312字符集----GB2312编码
    GBK字符集---GBK编码

    Unicode字符集(宽字符)----UTF8编码、UTF16编码、UTF32编码

    在C/C++程序中,我们使用char类型来存储单个字符('0','A'),一般而言, char类型的长度是1个字节,共有8位。
    也就是,一个char类型的变量ch,最多可以存储2^8=256个字符。
    但是,随着字符的国际化,各个国家的字符标点,已经远超256个字符。由此,产生了一种解决方案。

    多字节字符

    多字节字符: 一般来说,一个char是1个字节,之所以教多字节字符是因为,一个char类型的变量,表示一个字符的时候,可能是一个字节,也可能是多个字节。
    比如,你需要保存一个字符'A',已知字符'A'的编码是65,所以一个字节就可以表示。
    但是,如果你想表达’赵'这个字符,他的unicode编码对应的是0xD5D4,1个字节就不够用了,因为汉字的编码大于256.

    因此大家就是用多字节来表示一个字符来接觉得不够用的问题,但是前128个已经被占用了,具体可以查看ASCII编码。后来256也不够用了。
    而且由此也产生一个问题,试想:假如你有一个字符串:

    char ch[] = "abc赵钱孙123";

    那么你解析的时候,最好能对每个字符做一个标识:
    第一个字符a占用1个字节,
    第二个字符b占用1个字节
    第三个字符c占用1个字节
    第四个字符赵,占用2个字节
    第五个字符钱,占用2个字节
    第六个字符孙,占用2个字节
    第七个字符1,占用1个字节
    ...

    这样下来,如果存储一个带有中英文的字符,会比较麻烦,因为,你需要额外的一个数组,来表示上面的字符数组的每个元素,所占用的字节,这样才能正常解析。
    如此一来,简直太麻烦了。

    宽字符

    后来,宽字符应运而生。已知一个字节是8位,最多能表示256个字符,其实一个字节未必一定是8位的,也可以是16位,只不过大家用久了,默认都是一个字节是8位。
    所以,宽字符,其实言外之意,是可以用多个字节表示一个字符的,也就是所有的字符都是多个字节,而不是原来只是超过256的字符。
    比如,’赵‘这个字,用2个字节来表示,同样,‘A’也用两个字节来表示,这样虽然浪费了一部分内存空间(因为原来一个字节能表示的字符,现在都需要两个字节),但是,解析的时候会方便多了。
    也就是,所有的字符,都假设按照两个字节来表示,2^16=65536,6万多个字符,足以表示全世界所有的符号了。

    在C/C++中,宽字符类型wchar_t 它和我们熟悉的char类型是一样的,只不过,涉及宽字符的相关库函数,都要用宽字符类型的库函数来处理,一般有w作为前缀。名字和我们熟悉的差别并不大。
    比如库函数strlen()对应的是wcslen()。

    宽字符并不一定是Unicode,Unicode只是宽字符编码的一种实现。
    它有三种常见的编码方式:UTF-8(1个字节表示)、UTF-16(2个字节表示)、UTF-32(4个字节表示).

    int main(void)
    {
    	std::string strLocale = setlocale(LC_ALL, "");
    	wchar_t *pw = L"赵钱孙A";
    	wchar_t wc_buffer[100];
    	wsprintfW(wc_buffer, L"%s", pw);
    	wprintf(L"0x%x
    ",wc_buffer[0]);
    	wprintf(L"c:%c
    ",wc_buffer[0]);
    	return 0;
    }
    

    参考:
    http://blog.csdn.net/luoweifu/article/details/49382969
    《Windows程序设计 第5版 珍藏版》 (美) Charles Petzold著

    转载本Blog文章请注明出处,否则,本作者保留追究其法律责任的权利。 本人转载别人或者copy别人的博客内容的部分,会尽量附上原文出处,仅供学习交流之用,如有侵权,联系立删。
  • 相关阅读:
    activiti实战系列之动态表单 formService 自定义变量类型
    js向一个数组中插入元素的几个方法-性能比较
    Mac系统安装和配置tomcat步骤详解
    Spring注解之@validated的使用
    Spring注解之@Lazy注解
    centos命令行系列之升级glibc到
    docker实战系列之docker 端口映射错误解决方法
    centos命令行系列之centos6防火墙的关闭以及开启
    docker实战系列之搭建rabbitmq
    运营型模型
  • 原文地址:https://www.cnblogs.com/drfxiaoliuzi/p/7991337.html
Copyright © 2020-2023  润新知