gpt4 book ai didi

c++ - "C.UTF-8"Windows 上的 C++ 语言环境?

转载 作者:行者123 更新时间:2023-12-02 02:25:08 25 4
gpt4 key购买 nike

我正在修复一个大型开源跨平台应用程序,以便它可以处理 Windows 上包含非 ANSI 字符的文件路径。

<小时/>

更新:

根据我迄今为止得到的答案和评论(谢谢!)我觉得我应该澄清一些观点:

  1. 无法修改数十个第三方库的代码以使用std::wchar_t。这不是一个选择。该解决方案必须与普通的 std::fopen()std::ifstream 等一起使用。

  2. 我在下面概述的解决方案的运行率为 99%,至少在我正在开发的系统上(Windows 10 版本 1909,内部版本 18363.535)。我还没有在任何其他系统上进行过测试。

    唯一剩下的问题,至少在我的系统上,基本上是数字格式,我希望替换 std::numpunct 方面可以解决问题(但是我还没成功)。

<小时/>

我当前的解决方案包括:

  1. 在 Windows 上将 LC_CTYPE 类别的 C 语言环境设置为 .UTF-8(所有其他类别均设置为 C) > 应用程序所需的区域设置):

    // Required by the application.
    std::setlocale(LC_ALL, "C");

    // On Windows, we want std::fopen() and other functions dealing with strings
    // and file paths to accept narrow-character strings encoded in UTF-8.
    #ifdef _WIN32
    {
    #ifndef NDEBUG
    char* new_ctype_locale =
    #endif
    std::setlocale(LC_CTYPE, ".UTF-8");
    assert(new_ctype_locale != nullptr);
    }
    #endif
  2. 配置 boost::filesystem::path 以使用 en_US.UTF-8 语言环境,以便它也可以处理包含非 ANSI 字符的路径:

    boost::filesystem::path::imbue(std::locale("en_US.UTF-8"));

最后缺少的一点是使用 C++ 流修复文件 I/O,例如

std::ifstream istream(filename);

最简单的解决方案可能是在应用程序开头设置全局 C++ 语言环境:

std::locale::global(std::locale("en_US.UTF-8"));

但是这会扰乱数字的格式,例如1234.56 被格式化为 1,234.56。

是否有一个区域设置只是将编码指定为 UTF-8,而不会弄乱数字格式(或其他内容)?

基本上我正在寻找 C.UTF-8 语言环境,但 Windows 上似乎不存在。

更新:我想一种解决方案是重置语言环境的一些(大部分?全部?)方面,但我很难找到有关如何执行此操作的信息。

最佳答案

Windows API 不尊重 CRT 语言环境,fopen 等 CRT 实现直接调用narrow-char API,因此更改语言环境不会影响编码。

但是,Windows 10 May 2019 更新(版本 1903)introduced a support for UTF-8 in its narrow-char APIs 。可以通过将适当的 list 嵌入到可执行文件中来启用它。不幸的是,它是最近添加的,因此如果您需要针对较旧的系统,可能不是一个选择。

您的其他选项包括手动转换为 wchar_t 或使用为您执行此操作的层(例如 Boost.Filesystem,甚至更好,Boost.Nowide)。

关于c++ - "C.UTF-8"Windows 上的 C++ 语言环境?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59654829/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com