【问题标题】:sourcefile encoding UTF-8 no-bom and Visual Studio MFC源文件编码 UTF-8 no-bom 和 Visual Studio MFC
【发布时间】:2023-03-14 18:31:02
【问题描述】:

我在 C++ 文件(Visual Studio 2019,MFC 项目)中确实有那个简单的 coden-p

CString teststr = _T("täst"); //second letter is a german "Umlaut"
TRACE(_T("\n%s: %d"), static_cast<LPCTSTR>(teststr), teststr.GetLength());

VS 中源文件的默认编码是“西欧 (Windows) - 代码页 1252” - 至少在我的系统上是这样。

TRACE 为我提供了正确的文本和正确的长度 (4)。

但是,我想将 sourcefiles-encoding 更改为 UTF-8,以便将来能够独立于开发人员语言。

如果我将编码更改为“Unicode (UTF-8 with signature) - Codepage 65001)”,它仍然没问题,除了源文件有一个 BOM - 这是我不喜欢的。

当我将源代码保存为“Unicode (UTF-8 without signature) - Codepage 65001)”(这是我想使用的编码)时,真正的问题出现了。当我这样做时,源文件在编辑器中看起来仍然很好,但 TRACE 给了我:"täst: 5" 哪个原因是可怕的错误,并且是生产代码中可怕的错误和崩溃的来源。

所以问题是:如何在没有 BOM 的情况下将源代码保存为 UTF-8 并且仍然可以使用?是否有任何设置或扩展可能对此有所帮助?

【问题讨论】:

  • TRACE 必须进行窄到宽的字符串转换。标准 MFC 工具使用MultiByteToWideChar(CP_ACP,...),而不是MultiByteToWideChar(CP_UTF8,...),即它们假定窄字符串在“ANSI 代码页”中;但你的字符串实际上是 UTF-8。因此,您会在“调试”窗口中得到难以理解的输出。
  • 其实,没有。假设您进行 Unicode 构建,代码实际上是 CStringW s = L"täst";,它取决于 编译器 如何将源代码字符串转换为宽字符串。很有可能它还假设源文件在 CP1252 中。
  • “源文件得到一个 BOM - 我不喜欢的东西” - 你为什么要避免这个解决方案?这是你真正想要的。 BOM 明确地标识了文档的编码,任何消费者都可以从那里获取它。

标签: utf-8 mfc visual-studio-2019


【解决方案1】:

请参阅/utf-8 编译器选项,特别是(强调我的):

您可以使用/utf-8 选项将源字符集和执行字符集指定为使用UTF-8 编码的字符集。相当于在命令行中指定/source-charset:utf-8 /execution-charset:utf-8。默认情况下,这些选项中的任何一个也启用/validate-charset 选项。有关受支持的代码页标识符和字符集名称的列表,请参阅Code Page Identifiers

默认情况下,Visual Studio 会检测字节顺序标记以确定源文件是否采用编码的 Unicode 格式,例如 UTF-16 或 UTF-8。如果未找到字节顺序标记,则假定源文件使用当前用户代码页进行编码,除非您使用 /utf-8/source-charset 选项指定了代码页。 Visual Studio 允许您可以使用多种字符编码中的任何一种来保存您的 C++ 源代码。有关源和执行字符集的信息,请参阅语言文档中的 Character Sets

【讨论】:

    【解决方案2】:

    假设您进行 Unicode 构建,编译器实际看到的代码

    CStringW s = L"täst";
    

    这取决于编译器如何将源代码字符串转换为宽字符串。 MSVC 中的默认设置是没有 BOM 的源文件位于当前代码页中,在您的情况下为 CP1252。

    您可以使用/source-charset:utf-8 告诉编译器实际编码。您在项目设置的 Additional Options 字段中提供选项。

    See the compiler command line option.

    【讨论】:

      【解决方案3】:

      感谢您的回答,它们工作正常(/utf-8 编译器开关)

      现在我知道问题是在不同的源文件中有不同的编码,我不想将它们全部编码为 utf-8。 所以我不能全局告诉编译器如何处理 no-bom 文件

      所以我的解决方案是:不要将 utf-8 nobom 与 c++ 源一起使用,始终使用 bom 或将现有文件保留为 CP1252。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-09
        • 2017-02-23
        • 2020-01-25
        • 1970-01-01
        • 2016-05-03
        相关资源
        最近更新 更多