当面の課題
Windows で UTF-8 エンコードされた XML からファイル名を解析しています。そのファイル名を変更できない関数に渡す必要があります。内部的には_fsopen()
、Unicode 文字列をサポートしないものを使用します。
現在のアプローチ
私の現在のアプローチは、ファイル名がそのエンコーディングで表現可能であることを期待して、ファイル名をユーザーの文字セットに変換することです。次にboost::locale::conv::from_utf()
、UTF-8 から変換するために使用boost::locale::util::get_system_locale()
し、現在のロケールの名前を取得するために使用しています。
人生は素晴らしい?
コードページWindows-1252を使用しているドイツのシステムを使用しているため、 de_DE.windows-1252がget_system_locale()
正しく生成されます。ウムラウトを含むファイル名でアプローチをテストすると、すべてが期待どおりに機能します。
問題
システム ロケールを、コード ページWindows-1251を使用するウクライナ語に切り替えたことを確認するためです。ファイル名にキリル文字を使用すると、私のアプローチは失敗します。その理由は、get_system_locale()
現在は正しくないde_DE.windows-1252が生成されるためです。
一方GetACP()
、ドイツ語ロケールでは 1252、ウクライナ語ロケールでは 1251 が正しく生成されます。また、この小さなテスト プログラムが期待どおりに動作するため、Boost.Locale が特定のロケールに変換できることも知っています。
#include <boost/locale.hpp>
#include <iostream>
#include <string>
#include <windows.h>
int main()
{
std::cout << "Codepage: " << GetACP() << std::endl;
std::cout << "Boost.Locale: " << boost::locale::util::get_system_locale() << std::endl;
namespace blc = boost::locale::conv;
// Cyrillic small letter zhe -> \xe6 (ш on 1251, æ on 1252)
std::string const test1251 = blc::from_utf(std::string("\xd0\xb6"), "windows-1251");
std::cout << "1251: " << static_cast<int>(test1251.front()) << std::endl;
// Latin small letter sharp s -> \xdf (Я on 1251, ß on 1252)
auto const test1252 = blc::from_utf(std::string("\xc3\x9f"), "windows-1252");
std::cout << "1252: " << static_cast<int>(test1252.front()) << std::endl;
}
質問
Boost.Locale がサポートする形式でユーザー ロケールの名前を照会するにはどうすればよいですか? 使用するとGerman_Germany.1252
std::locale("").name()
が生成され、使用すると例外が発生します。boost::locale::conv::invalid_charset_error
システム ロケールがde_DE.windows-1252 のままである可能性はありますが、ローカル管理者として変更していると思われますか? 同様に、私のアカウントの言語は英語ですが、システム言語はドイツ語です。(ログイン画面はログインするまでドイツ語です)
短いファイル名を使用する必要がありますか? ただし、確実に機能していないようです。
細字
- コンパイラはMSVC18
- Boost はバージョン 1.56.0、バックエンドはおそらく winapi
- システムは Win7、システム言語はドイツ語、ユーザー言語は英語