C++/codecvt
外观
< C++
codecvt 是C++标准程式库中的一个头文件,定义了C++标准中的字符编码转化的几个基本模板类。
这个头文件主要包含 std::codecvt 类模板及其特化,支持字符编码之间的转换,例如从UTF-8 到 UTF-16,或从宽字符(wchar_t)到窄字符(char)等。std::codecvt 类通常与 std::wstring_convert 类一起使用,以实现字符编码转换。
语法 codecvt 命名空间中的主要类和函数如下:
codecvt_base:定义了编码转换的状态类型和错误处理方式。 codecvt_byname:模板类,用于创建特定编码的转换器。 codecvt_utf8、codecvt_utf16:特定编码的转换器类。
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wide_string = converter.from_bytes("Hello, World!");
std::string narrow_string = converter.to_bytes(L"你好,世界!");
类模板
[编辑]codecvt_utf8
[编辑]template<
class Elem,
unsigned long Maxcode = 0x10ffff,
std::codecvt_mode Mode = (std::codecvt_mode)0
> class codecvt_utf8 : public std::codecvt<Elem, char, std::mbstate_t>;
用于UTF-8编码的字节串 向/从 char16_t, char32_t, wchar_t的等宽字符串转化。可用于UTF-8编码的文件的读写,无论文本模式或二进制模式。
codecvt_utf16
[编辑]UTF-16与UCS2/UCS4等宽字符集之间的编码转化。
codecvt_utf8_utf16
[编辑]UTF-8与UTF-16之间的编码转化。
枚举型
[编辑]enum codecvt_mode {
consume_header = 4,
generate_header = 2,
little_endian = 1
};
使用
[编辑]通常使用类模板std::wstring_convert来实现各种宽字符与窄字符之间的转换。例如:
#include <iostream>
#include <locale>
#include <string>
#include <codecvt>
int main ()
{
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> conversion;
std::string mbs = conversion.to_bytes( u"\u4f60\u597d" );
std::cout << std::hex;
for (int i=0; i<mbs.length(); ++i)
std::cout << int(unsigned char(mbs[i])) << ' ';
std::cout << '\n';
return 0;
}
下面例子对文件流做utf8到宽字符转换:
#include <fstream>
#include <iostream>
#include <locale>
#include <codecvt>
#include <iosfwd>
int main()
{
// UTF-8 data with BOM
std::ofstream("c:\\temp\\text.txt") << u8"\ufeffz\u6c34\U000200fa"; // including latin small letter 'z' U+007a CJK ideograph "水"
// read the UTF8 file, skipping the BOM
std::wifstream fin("c:\\temp\\text.txt");
fin.imbue(std::locale(fin.getloc(),
new std::codecvt_utf8<wchar_t, 0x10ffff, std::consume_header>)); //std::codecvt_utf8 是一个模板类,提供了从 UTF-8 编码到其他字符类型(如 wchar_t)的转换支持。
// 采取的有效的Unicode字符集的最大值0x10ffff,即所有合法的 Unicode 字符都能被表示。
// std::consume_header 表示在进行编码转换时,如果存在 BOM(字节顺序标记),则会将其消费掉(即忽略 BOM),而不会将其作为字符输出。
std::cout << "Read from file using UTF-8/UCS2 codecvt\n";
for (wchar_t c; fin.get(c); )
std::wcout << std::hex << std::showbase << static_cast<unsigned short>(c) << '\n';
/* 输出为:
0x7a
0x6c34
0xfa */
std::wifstream fin1("c:\\temp\\text.txt");
fin1.imbue(std::locale(fin1.getloc(), new std::codecvt_utf8_utf16<wchar_t>));
std::cout << "Read from file using UTF-8/UTF-16 codecvt\n";
for (wchar_t c; fin1 >> c; )
std::wcout << std::hex << std::showbase << static_cast<unsigned short>(c) << '\n';
/* 输出为:
0x7a
0x6c34
0xd840
0xdcfa
*/
return 0;
}