21 октября 2009

Yo!

Отсортировать строки по алфавиту очень просто - все необходимые сведения о порядке символов есть в классе std::locale. Остается только надеяться что std::locale не подведет. А, как оказалось, она может. Вот пример:
struct lexicographical_order
{
std::locale Locale;

lexicographical_order(std::locale Locale) : Locale(Locale)
{
}

bool operator()(std::wstring const &lhs, std::wstring const &rhs) const
{
return boost::ilexicographical_compare(lhs, rhs, Locale);
}
};

int main()
{
std::vector v;
v.push_back(L"яблоко");
v.push_back(L"апельсин");
v.push_back(L"банан");
v.push_back(L"персик");
v.push_back(L"ёжик");

std::locale Locale(""); // используем текущую локаль системы
std::cout << Locale.name() << std::endl;
std::sort(v.begin(), v.end(), lexicographical_order(Locale));

_setmode(_fileno(stdout), _O_U16TEXT);
std::copy(v.begin(), v.end(), std::ostream_iterator(std::wcout, L"\n"));
return 0;
}

Под русской Windows получаем:
Russian_Russia.1251
ёжик
апельсин
банан
персик
яблоко

Буква "ё" явно пользуется у данной локали большей популярностью, чем все остальные. Ну прям хоть свою локаль пиши...

7 комментариев:

Анонимный комментирует...

Предполагаю, причина в пустой bkb некорректной локали: в данном случае сортировка прошла по коду символов, просто W1251-код буквы Ё меньше.

Raider комментирует...

локаль с пустым именем упоминается в стандарте как "the user's preferred locale", то есть это та локаль, которая установлена в системе. проблема видимо в том, что в Windows эта локаль - Russian_Russia.1251, а других русских локалей в Windows вроде как нет :(

Kirill V. Lyadvinsky комментирует...

локаль с пустым именем упоминается в стандарте как "implementation defined".

Анонимный комментирует...

А зачем локаль, если строки юникодные (и утф16)? Прошлый векъ, однака.

Анонимный комментирует...

последние две строки неправильные.
надо так

SetConsoleOutputCP (1251);
std::wcout.imbue (loc);
std::copy (v.begin (), v.end (), std::ostream_iterator< std::wstring, wchar_t >(std::wcout, L"\n"));

P.S. тестировал только в XP

Raider комментирует...

> А зачем локаль, если строки юникодные (и утф16)?

для сортировки по алфавиту. в юникоде нет понятия алфавита, а в локалях есть.

сравни, например, последовательность букв в украинском алфавите и последовательность, в которой эти символы идут в юникоде

ser комментирует...

Т.е. при переходе на Unicode строки сортировать нельзя :-D ? Да, что-то не подумали разработчики...