不是有分 UTF-8 版和 UTF-16 版的 unicode 么, wchar_t 说明微软的 API 偏向于使用 UTF-16 版的 unicode,为什么不用 UTF-8 版的字符串,还有 UTF-16 不是有可能出现两个 wchar_t 组成的字符么,那 windows 底层又是怎样定位坐标,对称,快速统计字数的. 如果不能解决单字符占用大小不统一问题,那么用 wchar_t 又相比使用 char 有什么优势呢
1
wevsty 2019-01-21 02:47:05 +08:00 2
这个问题要分几段来解释。
首先明确 UTF-8,UTF-16,UTF-32 都只是 Unicode 的一种实现方式。 UTF-8 发布于 1993 年 1 月,然在 1992 年发布的 Windows 3.1 就已经开始支持中文。 随后的 Windows 9X 系列对于各种语言延续了 ANSI 代码页+本地编码的方法,由于有海量的应用需要兼容,不抛弃历史包袱是没办法魔改了。 到 NT 内核的时代,Windows 2000 内核当时选用的是 UCS-2 编码,在当年 UCS-2 本身是可以保证 2 个字节表示'所有字符'的。NT 内核一直沿用下来(不管是大补还是小补) UCS-2 显然不能满足需求,那么与 UCS-2 完全兼容的 UTF-16 就是首选,毕竟可以保证以前的代码完全兼容,还能满足需求。 最后类型的问题: wchar_t 这个类型只代表是占 2 个字节的一个数据类型(早期的编译器中甚至直接定义为 unsigned short int ),这个类型本身和编码无关。char 也是一样,依然跟编码无关。 使用 wchar_t 表示采用 UTF-16 编码的字符只是一个约定俗成的东西,如果你乐意你也可以用 wchar_t 来保存 ASCII 字符之类的。 |
2
wevsty 2019-01-21 03:05:57 +08:00 1
补充一下:
Windows 在很多年以来一直不支持 UTF-8 作为 Windows 的代码页存在,所以实际上要想在 Windows 下面同时支持多国语言使用 UTF-16 几乎是唯一的选择。一直到 Windows 10 1803 (大概时间)才加入了 UTF-8 代码页,但是由此带来的巨大兼容性问题依然十分蛋疼。 另外对于 CPP 来说,从 C++17 标准开始终于增加了几个跟字符编码有关的类型( char16_t,char32_t ) |
3
ysc3839 2019-01-21 04:03:34 +08:00 1
@wevsty Windows XP 就已支持 UTF-8 代码页。
char16_t, char32_t 应该是 C++11 增加的 https://zh.cppreference.com/w/cpp/keyword/char16_t https://zh.wikipedia.org/wiki/C%2B%2B11 |
4
hjc4869 2019-01-21 08:57:01 +08:00 via iPhone 1
https://www.unicode.org/notes/tn12/
Unicode 官方推荐,为什么不用? |
5
mcdull619 2019-01-21 09:30:40 +08:00 1
都好专业 , 膜拜大神 .
|
6
thedrwu 2019-01-21 09:33:46 +08:00 via Android 1
用了 utf8 就不能兼容别的 ansi 扩展,已有的软件不能兼容,于是给每个 api 打了个 W 小尾巴。
然而真正 Unicode 之后,ucs2 不够用就有点尴尬了,导致一些程序不能正确处理 utf16。 |
7
hhhsuan 2019-01-21 09:40:21 +08:00 1
windows 历史包袱太重了,微软应该下决心砍掉重连。
|
8
wevsty 2019-01-21 09:55:57 +08:00 2
@ysc3839
忘记了,因为存在感实在太低。 UTF-8 代码页无法作为系统的默认代码页,系统的大多数 API 也不支持,这一点直到 Win10 才去改是十分确定的。在此之前 UTF-8 编码的字符串如果要跟系统交互,还是得转换成 UTF-16 或者本地编码去使用的。 查了一下 wikipedia https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows Microsoft Windows has a code page designated for UTF-8, code page 65001. Prior to Windows 10 insider build 17035 (November 2017),[7] it was impossible to set the locale code page to 65001, leaving this code page only available for: Explicit conversion functions such as MultiByteToWideChar The Win32 console command chcp 65001 to translate stdin/out between UTF-8 and UTF-16. char16_t 和 char32_t 确实是 C++11 就加到标准了,这个是我记错了。 |