将斯堪的纳维亚字母从 wstring 转换为字符串

Converting Scandinavian letters from wstring to string

目标

将包含 ÅåÄäÖöÆæØø 的 wstring 转换为 C++ 中的字符串。

环境

C++17,Visual Studio 社区 2017,Windows 10 Pro 64 位

描述

我正在尝试将 wstring 转换为字符串,并已实施建议的解决方案

// This is the code I use:
// Convert a wide Unicode string to an UTF8 string
std::string toString(const std::wstring &wstr)
{
    if (wstr.empty()) return std::string();
    int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
    std::string strTo(size_needed, 0);
    WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
    return strTo;
}

到目前为止一切顺利。

我的问题是除了英文字母外,我还必须处理斯堪的纳维亚字母 (ÅåÄäÖöÆæØø)。请注意下面的输入 wstring。

L"C:\Users\BjornLa\Å-å-Ä-ä-Ö-ö Æ-æ-Ø-ø\AEther Adept.jpg"

返回时它变成了...

"C:\Users\BjornLa\Å-å-Ä-ä-Ö-ö Æ-æ-Ø-ø\AEther Adept.jpg"

...这给我带来了一些麻烦。

问题

所以我想问一个经常被问到的问题,但有一点补充:

如何将包含斯堪的纳维亚字符的 wstring 转换为字符串?

所以,我做了一些额外的 read-up 并根据我收到的评论进行了试验。

转向解决方案很简单。只需将 CP_UTF8 更改为 CP_ACP!

然而... 如果您在 the MSDN method documentation 的两行之间阅读,Microsoft 建议实际上应该使用 CP_UTF8CP_ACP 的备注为:

This value can be different on different computers, even on the same network. It can be changed on the same computer, leading to stored data becoming irrecoverably corrupted. This value is only intended for temporary use and permanent storage should use UTF-16 or UTF-8 if possible.

此外,整个方法的注释如下:

The ANSI code pages can be different on different computers, or can be changed for a single computer, leading to data corruption. For the most consistent results, applications should use Unicode, such as UTF-8 or UTF-16, instead of a specific code page, unless legacy standards or data formats prevent the use of Unicode. If using Unicode is not possible, applications should tag the data stream with the appropriate encoding name when protocols allow it. HTML and XML files allow tagging, but text files do not.

因此,尽管这个 CP_ACP 解决方案对我的 test-cases 工作正常,但它是否是一个整体好的解决方案仍有待观察。