我明白 std::codecvt<char16_t, char>
在 C++11 中执行 UTF-16 和 UTF-8 之间的转换,并且 std::codecvt<char32_t, char>
执行 UTF-32 和 UTF-8 之间的转换。是否可以在 UTF-8 和 ISO 8859-1 之间进行转换?
考虑:
const char* s = "\u00C0";
如果我打印这个字符串并且我的终端编码设置为 UTF-8,我将看到字符 À
.但是,如果我将终端的编码设置为 ISO 8859-1,打印该字符串将不会打印出所需的字符。我将如何转换 s
变成一个字符串,打印时将显示字符 À
如果我的终端编码设置为 ISO 8859-1?
我知道这可以用 iconv 这样的库来完成,但我很好奇是否可以仅使用 C++ 标准库来完成。我问这个问题不是因为我不想使用 iconv,而是因为我真的不明白语言环境在 C++ 中是如何工作的。
最佳答案
除了标准强制编码外,C++ 还支持通过语言环境实现定义的编码列表:
#include <locale>
#include <codecvt>
#include <iostream>
template <typename Facet>
struct usable_facet : Facet {
using Facet::Facet;
};
using codecvt = usable_facet<std::codecvt_byname<wchar_t, char, std::mbstate_t>>;
int main() {
std::wstring_convert<codecvt> convert(new codecvt(".1252")); // platform specific locale strings
std::wstring w = convert.from_bytes("\u00C0");
}
不幸的是,wchar_t
的一个问题是标准 mandates只是它对所有语言环境都使用固定宽度编码,但不要求它在不同语言环境中使用相同编码,因此您不能可移植地转换为 wchar_t
使用一种语言环境,然后使用不同的语言环境将其转换回 char
。
使用类似 std::mbrtoc32
的函数可能会为此类转换提供一些可移植支持和相关功能,但这些尚未广泛实现。
I understand that this can be done with a library such as iconv, but I am curious whether it can be done using only the C++ standard library. I ask this question not because I don't want to use iconv, but because I don't really understand how locales work in C++.
语言环境库的设计并不适合现代使用。 C 和 C++ 本身混淆了编码与字符集,并且语言环境将词法和正字法问题与编码等计算方面混为一谈。
语言环境如何工作是一个比适用于 stackoverflow 答案更广泛的主题,但有 books关于这个话题。您可能还需要阅读特定于平台的 Material ,因为该标准并未真正为大部分功能提供任何上下文。例如,语言环境库支持消息目录,但不会告诉您它们是什么或您实际如何使用 make one因为 C++ 未对其功能进行标准化。
关于c++ - C++ 是否支持 UTF-8、UTF-16 和 UTF-32 以外的字符编码之间的转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24563521/