V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
绝不跟中二病患者辩论
doraos
V2EX  ›  中二病

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

  •  
  •   doraos · 2019-01-21 02:11:35 +08:00 · 2694 次点击
    这是一个创建于 2136 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    9 条回复    2019-01-21 12:45:11 +08:00
    wevsty
        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 字符之类的。
    wevsty
        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 )
    ysc3839
        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
    hjc4869
        4
    hjc4869  
       2019-01-21 08:57:01 +08:00 via iPhone   ❤️ 1
    https://www.unicode.org/notes/tn12/
    Unicode 官方推荐,为什么不用?
    mcdull619
        5
    mcdull619  
       2019-01-21 09:30:40 +08:00   ❤️ 1
    都好专业 , 膜拜大神 .
    thedrwu
        6
    thedrwu  
       2019-01-21 09:33:46 +08:00 via Android   ❤️ 1
    用了 utf8 就不能兼容别的 ansi 扩展,已有的软件不能兼容,于是给每个 api 打了个 W 小尾巴。

    然而真正 Unicode 之后,ucs2 不够用就有点尴尬了,导致一些程序不能正确处理 utf16。
    hhhsuan
        7
    hhhsuan  
       2019-01-21 09:40:21 +08:00   ❤️ 1
    windows 历史包袱太重了,微软应该下决心砍掉重连。
    wevsty
        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 就加到标准了,这个是我记错了。
    ysc3839
        9
    ysc3839  
       2019-01-21 12:45:11 +08:00 via Android   ❤️ 1
    @wevsty 即使作为系统活动代码页,系统内部还是会 decode 成 UTF-16 再进行处理的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5632 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 03:22 · PVG 11:22 · LAX 19:22 · JFK 22:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.