WIndows 11 默认 API 和 UTF 编码

Posted

技术标签:

【中文标题】WIndows 11 默认 API 和 UTF 编码【英文标题】:WIndows 11 Default API and UTF Encoding 【发布时间】:2022-01-09 02:03:42 【问题描述】:

在 Windows 10 及更早版本中,我已经能够将本地代码页 1250 中的字符串或使用以下代码的 CP_ACP 成功传输到 UTF-8。但在 Windows 11 中,这不再适用于 CP_ACP(而 1250 仍然有效)。似乎默认代码页现在是 65001,无法通过这种方式转换为 UTF-8。结果简直是假的。

原因可能是,我的例子中的字符串“Öf”没有正确编码为65001。现在我有一个大项目,用户输入字符串,各种第三方扮演角色,似乎都交付1250 中的字符串,或非欧洲用户的当前代码页。

这是为什么呢?又该怎么办?

#include <Windows.h>

#include <cstdio>

int main()

    printf("UTF Conversation Test\n");

    char line[1000];
    WCHAR uline[1000];
    char uline1[1000];

    line[0] = 214;
    line[1] = 104;
    line[2] = 0;

    char *s1 = line;
    while (*s1 != 0)
    
        printf("%10x %d\n", (int)*s1, (int)*s1);
        s1++;
    
    printf("\n");

    MultiByteToWideChar(1250, 0, line, -1, uline, 1000);
    // MultiByteToWideChar(CP_ACP, 0, line, -1, uline, 1000);

    WCHAR* s2 = uline;

    while (*s2 != 0)
    
        printf("%10x %d\n", (int)*s2, (int)*s2);
        s2++;
    
    printf("\n");

    WideCharToMultiByte(CP_UTF8, 0, uline, -1, uline1, 1000, 0, 0);

    char *s3 = uline1;

    while (*s3 != 0)
    
        printf("%10x %d\n", (int)*s3, (int)*s3);
        s3++;
    

【问题讨论】:

这能回答你的问题吗? Is codepage 65001 and utf-8 the same thing? docs.microsoft.com/en-us/windows/apps/design/globalizing/… printf("%d\n", GetACP()) 报告什么? CP_ACP 表示“使用本地编码”,这取决于 Windows 的本地化。 65001 是 UTF-8,而 Windows 11 显然更改了默认值(最后 ????)。如果您知道它是以这种方式编码的,请使用1250。明确。 您的示例 char[] 数组专门使用 Windows-1250 中的字符,因此永远使用 CP_ACP 将此类数据转换为 UTF- 没有意义16,由于CP_ACP不保证映射到代码页1250。直接使用代码页1250是正确的解决方案。仅在处理从用户处获得的文本时使用CP_ACP,即通过在 ANSI 模式下运行的 UI 控件(在这种情况下,您确实应该使用 UNICODE 模式)。代码页 65001 (CP_UTF8) 是 Microsoft 的 UTF-8 代码页,因此如果 char[] 数据以 UTF-8 开头,则无需通过 MultiByteToWideChar() 进行转换 【参考方案1】:

事实证明,Windows 11 默认情况下会在系统范围内激活对 UTF-8 的 Beta 支持。这意味着任何在内部不以 Unicode 存储字符串的程序都必须转换为 UTF-8 并返回以使用 Windows 服务,例如字符的屏幕输出。更糟糕的是,他们的一些对话可能会停止正确显示本地字符。一种解决方案是在时间和地区的管理设置中禁用此 Beta 支持。

【讨论】:

奇怪的是,Windows 11 会默认使用 beta 功能。我找不到微软关于此的任何公告。另一种可能是您安装了某个程序,而该程序偷偷将您的系统设置更改为 UTF8。尝试创建一个新的用户帐户并检查它是否仍然是 UTF8。 请注意,从长远来看,采用它是一件非常好的事情,它只会给转换当前应用程序带来一些问题。它将消除许多实际支持语言的奇怪问题,动机如下:utf8everywhere.org 当然,使用 Unicode 是正确的想法。 Java 从一开始就有 16 位 Unicode 字符。但是 Windows 总是要与向后兼容性作斗争,而 DOS 是严格的 8 位的。现在,我们必须与过去的阴影作斗争。对于我的程序,我正在使用 Visual Studio 2019 编译对话框。我希望 UI 能够尊重旧的编译并正确运行它们。 @Rene 虽然这在理论上是可能的,但如果有任何依赖于系统代码页的程序被设置为之前的默认值以外的东西,那么它必须很少。如果你确实有一个,我建议在程序之前创建一个运行 chcp 1253 或任何它需要的批处理文件。

以上是关于WIndows 11 默认 API 和 UTF 编码的主要内容,如果未能解决你的问题,请参考以下文章

将单声道编译为静态库

python 2.x编解码

windows文件名编码格式

'utf-8'编解码器无法解码位置1中的字节0xf4:无效的连续字节

DjangoUnicodeDecodeError:“utf8”编解码器无法使用 pyodbc-azure 解码

11.vue-router编程式导航