【问题标题】:How to make std::wofstream write UTF-8?如何使 std::wofstream 写入 UTF-8?
【发布时间】:2016-12-23 23:40:14
【问题描述】:

我正在将std::wclog 重定向到一个文件以登录我的程序:

std::wclog.rdbuf((new std::wofstream("C:\\path\\to\\file.log", std::ios::app))->rdbuf());

通过写信给std::wclog

std::wclog << "Schöne Grüße!" << std::endl;

令人惊讶的是,我发现该文件是用 ANSI 编写的。 (这对于ofstreamclog 来说是完全可以接受的,但我曾预计wofstreamwclog 会产生某种unicode 输出。)我也希望能够登录CYK 语言(例如用户输入),那么有没有办法让wofstream 生成 UTF-8? openmode 标志似乎没有提供这一点。

(如果没有平台无关的方式,我是Win7+ 64位的。)

编辑:

上面的问题有错误。线

std::wclog << "Schöne Grüße!" << std::endl;

应该是

std::wclog << L"Schöne Grüße!" << std::endl;

这只是为了演示我想要做什么,在现实生活中,wstring 被写入wofstream 来自一个提供翻译的类,比如

std::wclog << _(L"Best regards") << std::endl;

在哪里

#define _(X) i18n::translate(X)

class i18n {
public:
    static std::wstring translate(const std::wstring&);
}

所以我想做的是使用wofstringwstring 写入std::wclog 将其放入文件中,并且该文件应该是UTF-8 编码(没有BOM)。

【问题讨论】:

  • 为什么要将窄字符写入宽字符流?
  • 我想如果你想要的话,你需要使用 UTF 文字吗?那么语言环境呢?
  • 您需要为 Unicode 使用正确的类型和文字。 Visual C++ supports the C++11 Unicode 文字和类型。例如,`u8"hello"` 是 UTF-8 编码的 char*u"hello"char16_t*,而 u8"hello"su"hello"s 返回 std::stringstd::u16string。一般来说,最好使用 STL 字符串类型

标签: c++ logging utf-8 widechar


【解决方案1】:

您只需要使用 UTF8 文字,即:

std::wclog << u8"Schöne Grüße!" << std::endl;

结果是

Schöne Grüße!

如果你混合使用 ASCII 和 UTF8 文字,例如:

std::wclog << "Schöne Grüße!" << std::endl << u8"Schöne Grüße!" << 

std::endl;

非 ASCII 字符将被替换。

Sch?ne Gr??e!
Schöne Grüße!

Unicode 文字已添加到 C++ 11。它们首先在 Visual Studio 2015 中实现。String and Character Literals page 描述了目前 Visual C++ 中支持的文字。

【讨论】:

    【解决方案2】:

    openmode 标志似乎没有提供此功能。

    因为它与openmode无关。

    代码转换(即字符编码)由流使用的localecodecvt facet 执行。您可以使用转换为 UTF-8 的 codecvt facet 为 ostream 注入不同的语言环境。

    但我不知道这是否有必要。我不知道 Windows 的行为如何,但在健全的平台上,您只需编写包含 UTF-8 的窄字符串来阻塞,输出将是 UTF-8,您不需要使用宽流。 UTF-8 是使用单个八位字节的多字节编码,即窄字符。

    【讨论】:

    • 自 2000 年以来,Windows 的核心是 Unicode。这与 Windows 无关。人们认为当他们尝试打开没有 BOM 的文件时(因此没有迹象表明它们 不是 ANSI)并发现 Windows 假设他们使用用户输入的代码页作为 @ 987654326@
    • BTW w 只是表示宽,它没有指定编码。 C++11 为 UTF-8、UTF-16 和 UTF-32 添加了特定类型为 shown in this related questionreference 和 Visual C++ 的 relevant page
    • @PanagiotisKanavos “自 2000 年以来,Windows 的核心就是 Unicode”。那么你如何做 OP 想做的事情呢?
    • @PanagiotisKanavos “Windows 的核心是 Unicode”不是真的,我希望这是真的,但他们所做的是添加宽字符支持,它仍然被破坏。要在其核心上完全支持 Unicode,您需要一个 wchar 可以保存完整的字符,即 32 位,但在 Windows 中 wchar 是 16 位。
    • @AndersK。首先,您说的是 UTF-32,而 Unicode 指的是 UTF-16。 UTF-32 相对较新,但如果您使用正确的类型,您可以在 C++ 中使用 UTF32
    猜你喜欢
    • 2014-02-01
    • 1970-01-01
    • 2011-04-26
    • 2021-07-22
    • 2015-05-14
    • 2011-11-01
    • 2015-11-06
    • 1970-01-01
    相关资源
    最近更新 更多