本地化库
本地环境设施包含字符分类和字符串校对、数值、货币及日期/时间格式化和分析,以及消息取得的国际化支持。本地环境设置控制流 I/O 、正则表达式库和 C++ 标准库的其他组件的行为。
平面类别
表示系统提供的具名本地环境的 std::codecvt
std::codecvt_byname
template< class InternT, class ExternT, class State > |
std::codecvt_byname 是 std::codecvt 平面,封装于构造时指定的 locale 的多字节/宽字符转换规则。
标准库提供以下的独立特化:
定义于头文件 | |
std::codecvt_byname<char, char, std::mbstate_t> | 恒等转换 |
std::codecvt_byname<char16_t, char, std::mbstate_t> | 在 UTF-16 和 UTF-8 间转换 (C++11 起)(C++20 中弃用) |
std::codecvt_byname<char16_t, char8_t, std::mbstate_t> | 在 UTF-16 和 UTF-8 间转换 (C++20 起) |
std::codecvt_byname<char32_t, char, std::mbstate_t> | 在 UTF-32 和 UTF-8 间转换 (C++11 起)(C++20 中弃用) |
std::codecvt_byname<char32_t, char8_t, std::mbstate_t> | 在 UTF-32 和 UTF-8 间转换 (C++20 起) |
std::codecvt_byname<wchar_t, char, std::mbstate_t> | 在系统原生宽和单字节窄字符集间转换 |
成员函数
(构造函数) | 构造新的 codecvt_byname 平面(公开成员函数) |
(析构函数) | 析构 codecvt_byname 平面(受保护成员函数) |
std::codecvt_byname::codecvt_byname
explicit codecvt_byname( const char* name, std::size_t refs = 0 ); | ||
explicit codecvt_byname( const std::string& name, std::size_t refs = 0 ); | (C++11 起) |
为名为 name
的本地环境构造新的 std::codecvt_byname
平面。
refs
用于资源管理:在销毁最后一个保有平面的 std::locale 对象时,若 refs == 0 ,则实现销毁平面对象。否则,不销毁对象。
参数
name | - | 本地环境的名称 |
refs | - | 链接到该平面的引用数 |
std::codecvt_byname::~codecvt_byname
protected: |
销毁平面。
继承自 std::codecvt
成员类型
成员类型 | 定义 |
intern_type | internT |
extern_type | externT |
state_type | stateT |
成员对象
成员名 | 类型 |
id [静态] | std::locale::id |
成员函数
out | 调用 do_out ( std::codecvt<InternT,ExternT,State> 的公开成员函数) |
in | 调用 do_in ( std::codecvt<InternT,ExternT,State> 的公开成员函数) |
unshift | 调用 do_unshift ( std::codecvt<InternT,ExternT,State> 的公开成员函数) |
encoding | 调用 do_encoding ( std::codecvt<InternT,ExternT,State> 的公开成员函数) |
always_noconv | 调用 do_always_noconv ( std::codecvt<InternT,ExternT,State> 的公开成员函数) |
length | 调用 do_length ( std::codecvt<InternT,ExternT,State> 的公开成员函数) |
max_length | 调用 do_max_length ( std::codecvt<InternT,ExternT,State> 的公开成员函数) |
受保护成员函数
do_out [虚] | 从 internT 转换字符串为 externT 转换字符串,如在写入文件时 ( std::codecvt<InternT,ExternT,State> 的虚受保护成员函数) |
do_in [虚] | 从 externT 转换字符串为 internT ,如在从文件读取时 ( std::codecvt<InternT,ExternT,State> 的虚受保护成员函数) |
do_unshift [虚] | 为不完整转换生成 externT 字符的终止字符序列 ( std::codecvt<InternT,ExternT,State> 的虚受保护成员函数) |
do_encoding [虚] | 返回产生一个 internT 字符所需的 externT 字符数,若此值为常数 ( std::codecvt<InternT,ExternT,State> 的虚受保护成员函数) |
do_always_noconv [虚] | 测试平面编码是否对所有合法值为恒等转换 ( std::codecvt<InternT,ExternT,State> 的虚受保护成员函数) |
do_length [虚] | 计算转换成给定的 internT 缓冲区会消耗的 externT 字符串长度 ( std::codecvt<InternT,ExternT,State> 的虚受保护成员函数) |
do_max_length [虚] | 返回能转换成单个 internT 字符的最大 externT 字符数 ( std::codecvt<InternT,ExternT,State> 的虚受保护成员函数) |
继承自 std::codecvt_base
成员类型 | 定义 |
enum result { ok, partial, error, noconv }; | 无作用域枚举类型 |
枚举常量 | 定义 |
ok | 完成转换而无错误 |
partial | 未转换所有源字符 |
error | 遇到非法字符 |
noconv | 不要求转换,输入与输出类型相同 |
调用示例 windows
#include <iostream>
#include <sstream>
#include <locale>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <iterator>
#include <exception>
#include <Windows.h>
std::vector<std::wstring> locals;
BOOL CALLBACK MyFuncLocaleEx(LPWSTR pStr, DWORD dwFlags, LPARAM lparam)
{
locals.push_back(pStr);
return TRUE;
}
std::string stows(const std::wstring& ws)
{
std::string curLocale = setlocale(LC_ALL, NULL); // curLocale = "C";
setlocale(LC_ALL, "chs");
const wchar_t* _Source = ws.c_str();
size_t _Dsize = 2 * ws.size() + 1;
char *_Dest = new char[_Dsize];
memset(_Dest, 0, _Dsize);
wcstombs(_Dest, _Source, _Dsize);
std::string result = _Dest;
delete[]_Dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}
int main()
{
EnumSystemLocalesEx(MyFuncLocaleEx, LOCALE_ALTERNATE_SORTS, NULL, NULL);
for (std::vector<std::wstring>::const_iterator str = locals.begin();
str != locals.end(); ++str)
{
std::locale::global(std::locale(stows(*str)));
auto& use_facet = std::use_facet<std::codecvt_byname<wchar_t, char, std::mbstate_t>>(std::locale());
std::wstring internal = L"z\u00df\u6c34\U0001f34c";
// 注意 wstring_convert 能做下列内容
std::mbstate_t mb{}; // 初始迁移状态
std::string external(internal.size() * use_facet.max_length(), '\0');
const wchar_t* from_next;
char* to_next;
use_facet.out(mb, &internal[0], &internal[internal.size()], from_next,
&external[0], &external[external.size()], to_next);
// 为简洁起见跳过错误检查
external.resize(to_next - &external[0]);
std::cout << std::locale().name()
<< " The string in narrow multibyte encoding: " << external << std::endl;
}
return 0;
}
输出
de-DE_phoneb The string in narrow multibyte encoding: z?
es-ES_tradnl The string in narrow multibyte encoding: z?
hu-HU_technl The string in narrow multibyte encoding: z?
ja-JP_radstr The string in narrow multibyte encoding: zs水
ka-GE_modern The string in narrow multibyte encoding: z
x-IV_mathan The string in narrow multibyte encoding: z?
zh-CN_phoneb The string in narrow multibyte encoding: z
zh-CN_stroke The string in narrow multibyte encoding: z
zh-HK_radstr The string in narrow multibyte encoding: zs水
zh-MO_radstr The string in narrow multibyte encoding: zs水
zh-MO_stroke The string in narrow multibyte encoding: zs水
zh-SG_phoneb The string in narrow multibyte encoding: z
zh-SG_stroke The string in narrow multibyte encoding: z
zh-TW_pronun The string in narrow multibyte encoding: zs水
zh-TW_radstr The string in narrow multibyte encoding: zs水