Я пытаюсь создать простую программу для перечисления файлов на моих дисках, но я застрял на отличной границе UTF.
Я использую boost :: recursive_directory_iterator для перечисления файлов.Это прекрасно работает, но Windows настроена на «Французскую Канаду», и многие файлы и каталоги имеют французские символы (например, é, è, ç).Эти имена файлов не отображаются правильно на экране, и я использую wcout.Я вижу «▒» вместо острых символов.Даже boost :: filesystem :: ifstream не может открыть эти файлы.
Я пытался добавить "std :: locale :: global (std :: locale (" "))", но сначала это толькобросил исключение.Я обнаружил, что когда LANG установлен на «» во время выполнения программы, предыдущая команда больше не выдает, а только устанавливает языковой стандарт «C» вместо того, чтобы быть используемым ОС (что я ожидаю »)fr_CA.UTF-8 "или" fr_CA.ISO8859-1 ").Любое другое значение для LANG возвращает исключение ...
Что нужно сделать, чтобы программа cygwin gcc могла использоваться в мире i18n?
Я написал это для проверки различных идентификаторов локали:
#include <iomanip>
#include <iostream>
#include <locale>
using namespace std;
void tryLocale(string ID)
{
try{
cout << "Trying " << std::setw(18) << std::left << "\"" + ID + "\" ";
std::locale Loc(ID.c_str());
cout << "OK (" << Loc.name() << ")" << endl;
}catch(...){
cout << "FAIL" << endl;
}
}
const char *Locales[] = { "", "fr", "fr_CA", "fr_CA.UTF-8", "fr_CA.ISO8859-1", "C", 0};
int main()
{
cout << "Classic = " << std::locale::classic().name() << endl << endl;
int i = 0;
do
{ tryLocale(Locales[i]);
} while(Locales[++i]);
return 0;
}
И это дает мне этот вывод (без каких-либо LANG или LC_ALL):
Classic = C
Trying "" FAIL
Trying "fr" FAIL
Trying "fr_CA" FAIL
Trying "fr_CA.UTF-8" FAIL
Trying "fr_CA.ISO8859-1" FAIL
Если для LANG установлено значение "", первая "попытка" становится
Trying "" OK (C)
Исключение выдается на печать:
terminate called after throwing an instance of 'std::runtime_error'
what(): locale::facet::_S_create_c_locale name not valid