Y> Мне надо сравнить два std::string без учета регистра. Я написал свою
Y> функцию сравнения, все вроде Ok, но меня мучает такой вопрос: есть ли
Y> стандартные средства (библиотечные) для такого сравнения?

Если подробно и "правильно", там все очень долго и сложно, т.к. преобразование символов
в разный регистр зависит от того, какой объект std::locale использовать и может приводить
к разным сюрпризам вроде преобразования одного заглавного символа в несколько строчных
и наоборот. Вкратце, более-менее "стандартным", (в смысле, что в нем используются только
стандартные возможности) можно считать примерно такой вариант:

#include <string>
#include <locale>
#include <algorithm>

class ToUpper
{
public:
  ToUpper(const std::locale&);

  char operator()(char c) const
  {
    return m_ct.toupper(c);
  }

private:
  const std::ctype<char>& m_ct;
};

class ToLower
{
public:
  ToLower(const std::locale&);

  char operator()(char c) const
  {
    return m_ct.tolower(c);
  }

private:
  const std::ctype<char>& m_ct;
};

void to_upper(const std::string& in, std::string& out, const std::locale& lc)
{
  if (out.length() < in.length())
    out.resize(in.length());
  std::transform(in.begin(), in.end(), out.begin(), ToUpper(lc));
}

void to_lower(const std::string& in, std::string& out, const std::locale& lc)
{
  if (out.length() < in.length())
    out.resize(in.length());
  std::transform(in.begin(), in.end(), out.begin(), ToLower(lc));
}

int compare_no_case(const std::string& l, const std::string& r, const std::locale& lc)
{
  ToUpper transformer (lc);

  std::string l_nc;
  l_nc.resize(l.length());
  std::transform(l.begin(), l.end(), l_nc.begin(), transformer);

  std::string r_nc;
  r_nc.resize(l.length());
  std::transform(l.begin(), l.end(), r_nc.begin(), transformer);

  return l_nc.compare(r_nc);
}


Приведенный код можно оптимизировать и оптимизировать, но наглядность его от этого не увеличится
Существенным недостатком приведенного варианта является отсутствие поддержки преобразований,
приводящих к преобразованию одного символа в несколько или наоборот, но основная идея использования
std::locale для преобразования между регистрами должна быть ясна

P.S. также можно воспользоваться какими-нибудь нестандартными расширениями,
предоставленными поставщиком компилятора; например, _strcmpi.
Posted via RSDN NNTP Server 1.6 RC1
Автор: Павел Кузнецов    Оценить