C++不支持Unicode,即使utf8
今天,字符串unicode我们已经不需要常理的理由,但是,一些有编程语言的悠久历史。这仍然是一个头疼。
尽管第三方库支持的假设,C++事实上没有真正有效地支持unicode。即使utf8。(注意:本文讨论了在内存中的字符串编码方案,络数据流。)
STL的string模板诞生时,unicode还是理想中的固定16位编码。那时。Windows、Java等先后跨跃进unicode时代,而Unix/Linux受限于向后兼容而难以改变。那时Windows上的C++编程主要用用Win32 API,还不流行STL。而Unix/Linux上还基本不支持Unicode。STL的wstring,仅仅是将char模板參数替换成wchar_t,看起来似乎全然合理,事实上并没有经过实践检验。所以,Windows上的wstring至今一直处于实际上不可用的状态,各种IO时的编码转换都有问题。而Linux上的wchar_t是32位,太浪费内存所以全然不值得使用。(最新的标准针对unicode引入了char16_t和char32_t,以及u16string和u32string。
)
为什么Linux上的wchar_t是32位呢?由于gcc開始支持宽字符的时候,大约也是unicode的字符集突破16位编码极限的时候。
本来预期很充足的码位,出乎意料的不够了。unicode不得不做出调整。调整后,有了三种可选的unicode编码:
utf32:一个码位固定4字节,一个码位表示一个字符编码。
utf16:兼容之前的16位编码,一个码位2字节,但1或2个码位表示一个字符编码。
utf8:兼容ASCII编码,一个码位1字节,但1到6个码位表示一个字符编码。(现行标准事实上要求最多4个码位。但出于保障兼容性的原因,5、6个码位的情况是可能出现的,即使这算无效编码。)
(除此之外,还有字符组合和修饰符组合的情况。使得码位到字符的映射更加复杂。在此忽略。
)
utf8的出现,让Linux系统发现了新的机会。既然兼容ASCII,那么仅仅要系统的编码页新加一个utf8的,不就支持unicode了么。
非常自然的,Linux就走了这条路。
而Windows却不支持utf8的编码页。这让非常多写跨平台程序的人对微软非常是不满。而后,更有人宣称。Windows、Java、.NET等选错了unicode编码,utf8才是王道。
我非常希望字符编码有个完美的解决方式,但非常可惜,每当我们试图让它变得简单,它就变得更加复杂。最主要的问题:一个utf8编码的char数组。仅仅只是是一个字节buffer,在C/C++的标准库支持下,你根本无法把它当字符串来处理。
想要字符串长度?它仅仅能给你字节数,而不是字符数。
想要取第n个字符?它仅仅能给你第n个字节。想要把一个字符转大写?想推断一个字符是否是字母?它仅仅接受char类型的字符,也就是说仅仅支持ASCII字符……
即使说对一个不须要操作字符的程序,在C/C++程序里我们总是要为输入分配buffer的,那么预期输入n个字符的buffer。应该分配多少字节呢?没错,你仅仅能按最大可能n*6+1来分配。对内存暂时分配还好。要是一个数据库字段,你怎么办?这时即使是utf32都可能更省存储空间。
当然,绝大多数问题都能够通过使用一个第三方的unicode库来解决。假设认为专门的unicode库太heavy,至少还有boost的日常解决方式。仅仅要把全部字符串操作替换成专门的函数……(假设安全性对你的程序非常重要。你还要了解所用函数在遇到无效编码时的行为。由于这也是黑客突破安全检查的一种手段。)
可是,大多数的程序猿甚至并不清楚unicode编码。更不可能了解编码转换的复杂性,他们或者习惯了C风格的字节操作,或者来自Java等使用双字节unicode的语言。做着并不是字处理的软件,所以对学习复杂的unicode编码系统并无太大兴趣。所以,utf8在C/C++里,更象是专家级的解决方式,而并不是面向普通开发人员。理想情况下,C++能够凭借其强大的抽象和封装能力,包装出一个真正基于字符訪问的字符串类(Python3走了这条路。但有非常多批评的声音),然而现实中则非常难将其标准化。
那么Windows、Java、.NET、iOS等所使用的utf16呢?本质上,他们的支持都是有缺陷的。
由于他们開始时支持的事实上是utf16的前身UCS2,每一个字符固定2字节。而当utf16出现后。就权当UCS2用,也就是说双码位4字节的字符(unicode里称作BMP以外的字符)会被当作两个字符处理。
假设你的程序真的想要正确支持双码位的字符,就要改敲代码,使用高级字符串函数来訪问字符串,而不是直接用下标索引。仅仅是由于BMP以外的字符极其罕用,其程序猿并我们并不需要了解这些细节。
从正确性的透视,这不是。但一个有用的观点,非常有用。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
C++不支持Unicode,即使utf8的更多相关文章
- ASCII、Unicode和UTF-8等常见字符编码格式介绍
信息存储在计算机中是转换成二进制来存储的,二进制的发明据说是来源于中国阴阳八卦.后德国数理哲学大师莱布尼茨是最早接触中华文化的欧洲人之一,从他的传教士朋友鲍威特寄给他的拉丁文译本<易经>中 ...
- 字符编码笔记:ASCII,Unicode和UTF-8
很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的,于是他们把这称为"字节". 再后来,他们又做了一些可以处理 ...
- 简单几句话总结Unicode,UTF-8和UTF-16
概念 先说一说基本的概念,这包括什么是Unicode,什么是UTF-8,什么是UTF-16. Unicode,UTF-8,UTF-16完整的说明请参考Wiki(Unicode,UTF-8,UTF-16 ...
- unicode,ansi,utf-8,unicode big endian编码的区别
知乎--http://www.zhihu.com/question/23374078 http://wenku.baidu.com/view/cb9fe505cc17552707220865.html ...
- 关于几种编码详解(Unicode,UTF-8,GB系列)
最近学Python,老是被编码的问题搞得晕乎乎的,晚上看了好多篇博客,整理出来一个比较清晰的关于几种编码以及字符集的思路. 主要参考:http://blog.sina.com.cn/s/blog_6d ...
- 字符编码-UNICODE,GBK,UTF-8区别【转转】
字符编码介绍及不同编码区别 今天看到这篇关于字符编码的文章,抑制不住喜悦(总结的好详细)所以转到这里来.转自:祥龙之子http://www.cnblogs.com/cy163/archive/2007 ...
- UNICODE与UTF8和GBK之间的关系
http://wenku.baidu.com/link?url=bheGEzfSjEx-QX-ciME5oKooKYE08_NJZ02l2kKFa7kVZJ4t8Ks2uSNByovgP2QL6btq ...
- [Python] 中文编码问题:raw_input输入、文件读取、变量比较等str、unicode、utf-8转换问题
最近研究搜索引擎.知识图谱和Python爬虫比较多,中文乱码问题再次浮现于眼前.虽然市面上讲述中文编码问题的文章数不胜数,同时以前我也讲述过PHP处理数据库服务器中文乱码问题,但是此处还是准备简单做下 ...
- Windows 程序支持 Unicode
宽字符 阅读了 UTF-8 Everywhere 一文,推荐在程序中对于字符串都使用 UTF-8 编码.Unix-like 系统默认是支持 UTF-8 编码的Unicode字符串,标准库函数也默认支持 ...
随机推荐
- javascript笔记整理(对象基础)
一.名词解释 1.基于对象(一切皆对象,以对象的概念来编程) 2.面向对象编程(Object Oriented Programming,OOP) A.对象(JavaScript 中的所有事物都是对象) ...
- Ajax技术——带进度条的文件上传
1.概述 在实际的Web应该开发或网站开发过程中,经常需要实现文件上传的功能.在文件上传过程中,经常需要用户进行长时间的等待,为了让用户及时了解上传进度,可以在上传文件的同时,显示文件的上传进度条.运 ...
- teamviewer无法启动
在 Linux.Mac OS X和 Windows下都可以用,但在 Linux 下无法启动时怎么办? 笔者回家工作时,都会用 Teamviewer 连线到其他 Linux 桌面,但某天起 Teamvi ...
- 水平线、垂直线——axure线框图部件库介绍
1. 将水平线.垂直线拖动到axure页面编辑区域,如图: 2. 水平线.垂直线相关属性设置 主要属性有.线条的颜色.粗细.线条的样式.箭头的样式 来自:非原型不设计
- 《UNIX环境高级编程》笔记--read函数,write函数,lseek函数
1.read函数 调用read函数从文件去读数据,函数定义如下: #include <unistd.h> ssize_t read(int filedes, void* buff, siz ...
- Android NDK 简单介绍、工具安装、环境配置
NDK全称:Native Development Kit. 1.NDK是一系列工具的集合. * NDK提供了一系列的工具,帮助开发人员高速开发C(或C++)的动态库,并能自己主动将so和java应用一 ...
- 【实战】静默安装-oracle 11.2.0.3 on centos 5.10
发现网上静默安装的文章非常多,乱七八糟,五花八门!来个扫盲的! centos 5.10 下安装oracle 11g_r2 ************************************* ...
- Thinkphp入门 一 (45)
原文:Thinkphp入门 一 (45) 什么是框架? 就是一堆代码的集合,这些代码可以有变量.常量.函数.类等等.这些代码彼此紧密联系,彼此有合作关系.里边还有设计模式:MVC.单例.工厂等等. 为 ...
- 基于Hadoop技术实现的离线电商分析平台(Flume、Hadoop、Hbase、SpringMVC、highcharts)
离线数据分析平台是一种利用hadoop集群开发工具的一种方式,主要作用是帮助公司对网站的应用有一个比较好的了解.尤其是在电商.旅游.银行.证券.游戏等领域有非常广泛,因为这些领域对数据和用户的特性把握 ...
- JavaScript快速入门(三)——JavaScript语句
JavaScript基本语句 基本概述 JavaScript是脚本语言,从上到下解释执行,最小单位为语句或语句块,每个语句以分号结尾,每个语句块以右大括号结尾. JavaScript可以将多条语句或语 ...