小白请问微软为什么偏向于使用 wchar_t 版的 unicode

2019-01-21 02:11:35 +08:00
 doraos

不是有分 UTF-8 版和 UTF-16 版的 unicode 么, wchar_t 说明微软的 API 偏向于使用 UTF-16 版的 unicode,为什么不用 UTF-8 版的字符串,还有 UTF-16 不是有可能出现两个 wchar_t 组成的字符么,那 windows 底层又是怎样定位坐标,对称,快速统计字数的. 如果不能解决单字符占用大小不统一问题,那么用 wchar_t 又相比使用 char 有什么优势呢

2519 次点击
所在节点    中二病
9 条回复
wevsty
2019-01-21 02:47:05 +08:00
这个问题要分几段来解释。
首先明确 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 字符之类的。
wevsty
2019-01-21 03:05:57 +08:00
补充一下:
Windows 在很多年以来一直不支持 UTF-8 作为 Windows 的代码页存在,所以实际上要想在 Windows 下面同时支持多国语言使用 UTF-16 几乎是唯一的选择。一直到 Windows 10 1803 (大概时间)才加入了 UTF-8 代码页,但是由此带来的巨大兼容性问题依然十分蛋疼。

另外对于 CPP 来说,从 C++17 标准开始终于增加了几个跟字符编码有关的类型( char16_t,char32_t )
ysc3839
2019-01-21 04:03:34 +08:00
@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
hjc4869
2019-01-21 08:57:01 +08:00
https://www.unicode.org/notes/tn12/
Unicode 官方推荐,为什么不用?
mcdull619
2019-01-21 09:30:40 +08:00
都好专业 , 膜拜大神 .
thedrwu
2019-01-21 09:33:46 +08:00
用了 utf8 就不能兼容别的 ansi 扩展,已有的软件不能兼容,于是给每个 api 打了个 W 小尾巴。

然而真正 Unicode 之后,ucs2 不够用就有点尴尬了,导致一些程序不能正确处理 utf16。
hhhsuan
2019-01-21 09:40:21 +08:00
windows 历史包袱太重了,微软应该下决心砍掉重连。
wevsty
2019-01-21 09:55:57 +08:00
@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 就加到标准了,这个是我记错了。
ysc3839
2019-01-21 12:45:11 +08:00
@wevsty 即使作为系统活动代码页,系统内部还是会 decode 成 UTF-16 再进行处理的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/528941

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX