如何将ISO639-3三字母语言名称(例如“ PLK”,“ DEU”,“ ENU”)转换为语言代码(例如,对于PLK为0x0415,对于DEU为0x0407,对于ENU为0x0409)或转换为文化名称(例如,PLK是“ pl-PL”,DEU是“ de”,ENU是“ en-US”)?
我需要在以下代码行中进行反向转换:
GetLocaleInfoA(0x0415, LOCALE_SABBREVLANGNAME, buffer.data(), buffer.size());
// now buffer will have "PLK"
我希望能够写类似的东西:
LCID langCode = SomeMagicalFunctionThatISearchFor("PLK");
//and landCode should be now 0x0415 (1045 in decimal)
我的代码针对Microsoft Windows,因此可以使用WinAPI。
答案 0 :(得分:2)
static LCID lcid = -1;
::EnumSystemLocalesEx([](LPWSTR a1, DWORD a2, LPARAM a3) -> BOOL {
const int cch = 512;
wchar_t wcBuffer[cch] = { 0 };
int iResult = ::GetLocaleInfoEx(a1, LOCALE_SABBREVLANGNAME, wcBuffer, cch);
if(iResult > 0 && 0 == ::_wcsicmp(L"PLK", wcBuffer))
{
lcid = ::LocaleNameToLCID(a1, 0);
return FALSE;
}
return TRUE;
}, LOCALE_ALL, NULL, nullptr);
答案 1 :(得分:1)
因为它似乎不存在,所以您可以构建自己的。如果您需要进行很多查找,则unordered_map
应该可以解决这一问题,以保持信息的存储,以便快速访问。
#include <iostream>
#include <unordered_map>
#include <string_view>
#include <Windows.h>
class LocaleAbbr {
public:
LocaleAbbr() {
// enumerate all locales and call "proxy" for each one
::EnumSystemLocalesEx(proxy, LOCALE_ALL, reinterpret_cast<LPARAM>(this), nullptr);
}
LCID operator[](std::wstring_view abbr) const {
// operator to query for LCID from abbreviation
return name_lcid_map.at(abbr.data());
}
private:
BOOL callback(LPWSTR Arg1, DWORD Arg2) {
// extract abbreviation and LCID
wchar_t Buffer[512];
int rv = ::GetLocaleInfoEx(Arg1, LOCALE_SABBREVLANGNAME, Buffer, 512);
if (rv > 0) // put result in a name->LCID map:
name_lcid_map.emplace(Buffer, ::LocaleNameToLCID(Arg1, 0));
return TRUE;
}
static BOOL proxy(LPWSTR Arg1, DWORD Arg2, LPARAM Arg3) {
// cast Arg3 to "this" (set in the constructor) and call "callback"
return reinterpret_cast<LocaleAbbr*>(Arg3)->callback(Arg1, Arg2);
}
std::unordered_map<std::wstring, LCID> name_lcid_map;
};
int main() {
LocaleAbbr abbr;
std::wcout << abbr[L"PLK"];
}