C ++ Трехбуквенное название языка для LCID - PullRequest
4 голосов
/ 01 июля 2019

Как я могу преобразовать трехбуквенные имена языков ISO639-3 (например, «PLK», «DEU», «ENU») в языковые коды (то есть. 0x0415 для PLK, 0x0407 для DEU, 0x0409 для ENU) или в культуруимя (например, "pl-PL" для PLK, "de" для DEU, "en-US" для ENU)?

Мне нужно сделать обратное преобразование из одного вследующая строка кода:

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.

Ответы [ 2 ]

2 голосов
/ 01 июля 2019
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 голос
/ 01 июля 2019

Вы можете построить свой собственный, так как кажется, что он не существует.Если вам нужно выполнить много поисков, 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"];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...