【问题标题】:Why does Windows use ANSI Code page instead of UNICODE?为什么 Windows 使用 ANSI 代码页而不是 UNICODE?
【发布时间】:2017-10-11 00:20:30
【问题描述】:

当我在cmd.exe 窗口中运行命令chcp 时,它代表Windows 中使用的代码页。

我认为 Windows 使用 UNICODE 字符集。

所以,我的问题是:

  1. 为什么 Windows 使用 ANSI 代码页而不是 Unicode?​​p>

  2. Windows 使用 UTF-16 还是 UCS-2?我可以检查这个(通过命令或 MSDN 链接)吗?

  3. UTF-16 或 UCS-2 只是一种编码?还是也是一个字符集?

  4. UTF-8, UTF-16, UTF-32, etc .. 它们有不同的字符集大小吗?

我很困惑。请有人定义它们。

【问题讨论】:

  • 更改控制台的代码页只会影响非 Unicode 应用程序。 AFAIK 控制台仍然只支持 UCS-2,但当然大多数 Windows 应用程序都是 GUI 并且不使用控制台。
  • 控制台中的字符单元使用 16 位字符代码。这限制了它可以向 BMP 显示的内容。可以将 UTF-16 代理对写入相邻单元格,在这种情况下,它们将显示为两个默认字形,例如带框的问号。 FWIW,您可以将代理对复制并粘贴到另一个窗口。控制台也不使用 Uniscribe 或 DirectWrite,因此不支持复杂的脚本、组合字符和自动回退字体。您可以通过注册表中的手动字体链接来提高字形覆盖率。
  • 1) 为什么 Windows 使用 ANSI 代码页而不是 UNICODE? 真正的控制台同时使用 Unicode 和多字节 api。所有内部函数都使用 Unicode。显示为 Unicode 的文本。 CP 仅用于翻译输入/输出 Unicode 多字节。如果我们调用WriteConsoleW,文本将按原样显示,当前 CP 没有任何影响。如果我们调用WriteConsoleA - text first 将通过MultiByteToWideChar 转换为 Unicode,CP 将用作此处的第一个参数。所以A api 调用结果取决于当前的CP,而W 不是。和chcp 仅对当前cmd.exe 有效
  • @RbMm,我假设您的意思是当前控制台,而不仅仅是连接到控制台的 CMD shell。 CMD 只是一个控制台客户端应用程序,就像任何其他控制台应用程序一样。 chcp.com 是一个简单的控制台应用程序,它调用GetConsoleCPSetConsoleCPSetConsoleOutputCP。它不允许设置独立于输入代码页的输出代码页。值得注意的是,控制台的输入和输出代码页在通过ReadFileWriteFile 用作通用文件时使用,不支持UTF-16LE(代码页1200)。
  • 感谢您的回复。我添加了第 4 个问题,请回复。

标签: windows unicode encoding utf-16 ucs2


【解决方案1】:
  1. 历史原因和向后兼容性。 Windows 本身是一个基于 Unicode 的操作系统,从 NT 时代就一直如此。但是许多遗留(甚至是当前)应用程序并不是为 Unicode 编写的。支持 Unicode 的应用不使用 ANSI 代码页,除非它们需要在 ANSI 和 Unicode 之间转换运行时数据。

  2. Microsoft 在 Windows 2000 中切换到 UTF-16。在此之前,它使用的是 UCS-2。见Unicode in Microsoft Windows

  3. UTF-16 和 UCS-2 都只是相同 Unicode 字符集的编码。 UTF-16 的发明是为了支持 U+FFFF 以上的编码代码点,而 UCS-2 无法处理。

  4. 所有 UTF(包括许多您尚未命名的)都只是相同 Unicode 字符集的编码。名称中指定的数字是编码代码单元中使用的位数(UTF-8 使用 8 位代码单元,UTF-16 使用 16 位代码单元等)。

【讨论】:

  • UTF-16 是一种字符编码。 UCS-2 是一个字符集。当开始在 Windows NT 上工作时,它们本质上是一样的。数字上,而不是语义上。正如您在要点 2 和 3 中指出的那样,在 Windows 2000 之前,这种区别并不那么重要。
  • "启用 Unicode 的应用程序不使用 ANSI 代码页" 您如何“启用 unicode”应用程序?我找不到任何相关信息
  • @Barnack 在您的代码中使用 Unicode 字符串和 Unicode API,而不是使用 ANSI 字符串和 ANSI API。首先确保您的项目配置为使用 Unicode 字符集,以便在编译期间定义 ``UNICODE` 和 _UNICODE 条件,使所有 TCHAR/_TCHAR-based variables and C/Win32 APIs to use wchar_t` 而不是 char .查看编译器的文档了解更多详情
  • @RemyLebeau wchar_t 在处理 unicode 方面做得更好,因为它最多支持两个字节。它仍然不支持 unicode 编码。它当然不包括 utf-8,这是您应该在主要使用西方字符串以避免内存浪费的程序中使用的。
  • @Barnack wchar_t 在 Windows 2000 之前被解释为 UCS-2,但自 2000 年以来 wchar_t 现在被解释为 UTF-16,是的。至于char 和 UTF-8,大多数版本的 Windows 不理解 UTF-8(除了少数孤立的情况,例如 MultiByteToWideChar()/WideCharToMultiByte() API、fopen() 的扩展、chmod cmd 控制台等的命令)。但在 Windows 10 Insider build 17035 中,微软终于为旧版 Win32 ANSI API 添加了 UTF-8 代码页支持(即将char 字符串解释为 UTF-8 而不是 ANSI),但该功能目前处于测试阶段
猜你喜欢
  • 2017-08-28
  • 2011-03-01
  • 1970-01-01
  • 2011-10-28
  • 2013-11-13
  • 1970-01-01
  • 2012-02-20
  • 2023-03-19
  • 1970-01-01
相关资源
最近更新 更多