std::locale多语言切换
std::locale 使用总结:
std::locale可以结合use_facet来使用:
常见的user_facet有结合ctype、codecvt、time_get、time_put等,下面结合time_get和ctype为例分别讲解用法和调试过程中遇到的问题
使用ctype获取多语言字母
std::stringstream ss{};
std::locale loc("");
locale loc1("de_DE"), loc2("English_Australia");
ss.imbue(loc1);
bool result1 = use_facet<ctype<char>>(loc1).is(
ctype_base::alpha, '\xe4'
);
bool result2 = use_facet<ctype<char> >(loc2).is(ctype_base::alpha, '!'
);
if (result1)
ss << "The character" << '\xe4' << "'in locale loc1 is alphabetic."
<< endl;
else
ss << "The character" << de_char[28] << "in locale loc1 is not alphabetic."
<< endl;
if (result2)
ss << "The character '!' in locale loc2 is alphabetic."
<< endl;
else
ss << "The character '!' in locale loc2 is not alphabetic."
<< endl;
ss << loc.name() << endl;
注意:
- vs中编码页默认是基于936编码页,如果要输入特殊德语字符,这里需要调整添加额外编译选项参数/utf8
- 德语中的特殊字母是无法通过VS编译的程序窗口界面正常显示的,除非修改系统语言区域为德语。
- 如果系统为简体中文,想获取德语字母在utf8中的二进制,可以通过如下方式获取,在nodepad++中切换语言为德语输入对应德语字母,然后修改保存为utf8格式即可获取对应的二进制编码
使用time_get获取多语言表示
std::stringstream ss{};
//std::locale::global(std::locale("en_US.UTF-8"));
std::locale loc("zh-CN.UTF-8");
std::tm time_info;
std::istringstream iss("周四");
istreambuf_iterator<char> end;
std::ios_base::iostate err = std::ios_base::goodbit;
const std::time_get<char>& dateReader = use_facet<time_get<char>>(loc);
dateReader.get(iss, end, iss, err, &time_info,'a');
ss.imbue(std::locale("zh-CN"));
ss << std::put_time(&time_info, "%a");
return ss.str().c_str();
注意:
- 中文对应的locale为zh-CN,具体可以通过遍历系统支持的locale来查看本机使用的语言对应的locale
- 这里通过time_get和use_facet的结合使用方式来转换,如果iss中的字符和loc对应的多语言存储不一致会导致crash异常。
- user_face能够存储loc的原因是通过_GetCat的静态方法将locinfo作为构造入参
- ‘a’,‘A’ 是weekday的含义,注意iss输入字符一定要和‘a’ 以及locinfo语言保持匹配上
本地迭代获取支持的locale
BOOL CALLBACK MyFuncLocaleEx(LPWSTR pStr, DWORD dwFlags, LPARAM lparam)
{
locals.push_back(pStr);
return TRUE;
}
EnumSystemLocalesEx(MyFuncLocaleEx, LOCALE_ALTERNATE_SORTS, NULL, NULL);
std::wstringstream ss{};
for (vector<wstring>::const_iterator str = locals.begin(); str != locals.end(); ++str)
ss << *str << endl;