【问题标题】:byte representation of ASCII symbols in std::wstring with different locales具有不同语言环境的 std::wstring 中 ASCII 符号的字节表示
【发布时间】:2016-06-01 21:36:05
【问题描述】:

Windows C++ 应用程序。我们有一个只包含 ASCII 符号的字符串:std::wstring(L"abcdeABCDE ... any other ASCII symbol")。请注意,这是使用 wchar_tstd::wstring

问题 - 这个字符串的字节表示是否取决于本地化设置或其他?我可以假设如果我在应用程序运行时收到这样的字符串(例如,来自 WindowsAPI),它的字节数将与我的 PC 上的相同吗?

【问题讨论】:

  • 您使用的是 Unicode 字符串,在运行时以 utf-16 编码。它不依赖于语言环境,它是 Unicode。您从 winapi 获得的任何东西都将是 Unicode 以及带有 UNICODE #defined 的。具有非 ASCII 字符的字符串文字确实取决于您的文本编辑器将 .cpp 文件保存为编译器可以识别的 Unicode 编码,使用带有 BOM 的 utf-8,这样当您的源代码传输到其他地方时它不会变成 mojibake。
  • @HansPassant 谢谢你的提示!但我只需要小范围的 ASCII 符号(a-zA-Z、空格、点)。我对 Windows/Unicode 的东西没有丰富的经验,因此我要求 100% 确定。似乎我是对的,这些符号的表示不依赖于任何东西。
  • 忘记 ASCII 可能会有所帮助。在 Win32 API 中,您使用的是 Unicode/UTF-16。几乎没有人会使用整个 Unicode 字符集,所以几乎每个程序都会使用 Unicode 的一个子集。您使用的子集是否也是您未使用的字符集的子集并不重要。
  • @TomBlodget:源代码可能不是 UTF-16,所以我认为 ASCII 在这里仍然是相关的。
  • @HarryJohnston 不管它是什么,它不太可能是 ASCII 而不是 UTF-16。用户以一种特定的编码保存文件,编译器必须知道那是什么。创建和保存时,我的 VS2015 似乎默认为 Windows-1252,并让编译器默认使用可能相同的约定。不是很受控制,这导致了汉斯的推荐。

标签: c++ windows locale wstring


【解决方案1】:

一般来说,对于字符(不是转义序列)wchar_twstring 必须使用与 ASCII 相同的代码(只是扩展为 2 个字节)。 但我不确定小于 32 的代码,当然大于 128 的代码在输出时可能具有不同的含义(如 ASCII 码),因此为了避免输出设置特定语言环境的问题,例如:

  locale("en_US.UTF-8")

标准输出

  wcout.imbue(locale("en_US.UTF-8")); 

更新:

我发现了另一个关于添加的建议

  std::ios_base::sync_with_stdio(false);

在使用 imbue 设置本地化之前

查看How can I use std::imbue to set the locale for std::wcout?的详细信息

【讨论】:

  • 谢谢!!!我只需要窄范围的 ASCII 符号 - 字符 a-zA-Z 和几个特殊符号,如空格、点等。现在我更有信心了))
【解决方案2】:

文字字符串的字节表示不依赖于环境。它从编辑器硬编码为二进制数据。但是,解释二进制数据的方式取决于当前的代码页,因此在运行时转换为宽字符串时可能会得到不同的结果(与使用前导 L 定义字符串相反,这意味着宽字符将在编译时设置。)

为安全起见,请使用setlocale() 来保证用于转换的编码。那你就不用担心环境了。

这可能会有所帮助:“根据定义,ASCII 字符集是所有多字节字符集的子集。在许多多字节字符集中,0x00 – 0x7F 范围内的每个字符与在ASCII 字符集。例如,在 ASCII 和 MBCS 字符串中,1 字节的 NULL 字符 ('\0') 的值为 0x00,表示终止的空字符。"

来自: Visual Studio Character Sets 'Not set' vs 'Multi byte character set'

【讨论】:

    猜你喜欢
    • 2013-12-06
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-23
    • 2021-05-20
    • 1970-01-01
    相关资源
    最近更新 更多