Сравнение символов без учета регистра сложно, если вы хотите поддерживать символы из других языков. Вот почему это хорошая идея, чтобы сделать их с учетом местных условий:
struct char_iless
: public std::binary_function<char, char, bool>
{
std::locale loc;
char_iless(std::locale const & loc=std::locale()) : loc(loc)
{
}
bool operator()(char a, char b) const
{
return std::tolower(a, loc) < std::tolower(b, loc);
}
};
Вот как вы используете этот класс для сравнения двух символов:
char_iless('a', 'b', my_locale);
Просто используйте std::locale()
как my_locale
, если хотите использовать тот, который установлен по умолчанию.
Если вы можете использовать Boost, тогда в библиотеке String Algorithms есть функтор am is_iless
, который делает то же самое.
Расширить это от сравнения символов до строк легко благодаря std::lexicographical_compare
:
struct str_iless
: public std::binary_function<std::string, std::string, bool>
{
std::locale loc;
str_iless(std::locale const & loc=std::locale()) : loc(loc)
{
}
bool operator()(std::string const & a, std::string const & b) const
{
return std::lexicographical_compare(
a.begin(), a.end(),
b.begin(), b.end(),
char_iless(loc)
);
}
};
Теперь у вас есть все, что нужно для решения вашей проблемы:
int main()
{
std::list<std::string> list;
list.push_back("C");
list.push_back("a");
list.push_back("b");
// Sort using default locale
list.sort(str_iless());
// Sort using French locale
// (warning: this locale format string is MS specific)
std::locale loc("French_France.1252");
list.sort(str_iless(loc));
}