Подтвердить что ты не робот

Сравнение wstring с игнорированием случая

Я уверен, что это было бы задано раньше, но не могло найти его. Есть ли встроенный (т.е. Используемый методами std:: wstring или алгоритмы) путь к нечувствительному к регистру сравнению двух объектов wstring?

4b9b3361

Ответ 1

Если вы не против привязываться к реализации Microsoft, вы можете использовать эту функцию, определенную в <string.h>

int _wcsnicmp(
   const wchar_t *string1,
   const wchar_t *string2,
   size_t count 
);

Но если вам нужно лучшее соотношение производительности/совместимости/функциональности, вам, вероятно, придется искать дополнительную библиотеку (в любом случае это часть stl). Простой пример (взятый из другого ответа на другой вопрос):

#include <boost/algorithm/string.hpp>

std::wstring wstr1 = L"hello, world!";
std::wstring wstr2 = L"HELLO, WORLD!";

if (boost::iequals(wstr1, wstr2))
{
    // Strings are identical
}

Ответ 2

Использование стандартной библиотеки:

bool comparei(wstring stringA , wstring stringB)
{
    transform(stringA.begin(), stringA.end(), stringA.begin(), toupper);
    transform(stringB.begin(), stringB.end(), stringB.begin(), toupper);

    return (stringA == stringB);
}

wstring stringA = "foo";
wstring stringB = "FOO";
if(comparei(stringA , stringB))
{
    // strings match
}

Ответ 3

Вы можете использовать std:: tolower(), чтобы преобразовать строки в нижний регистр или использовать функцию wcscasecmp, чтобы сделать регистр, нечувствительный к регистру c_str.

Вот функтор сравнения, который вы можете использовать напрямую:

struct ci_less_w
{
  bool operator() (const std::wstring & s1, const std::wstring & s2) const
  {
      #ifndef _WIN32
            return wcscasecmp(s1.c_str(), s2.c_str()) < 0;
      #else
            return _wcsicmp(s1.c_str(), s2.c_str()) < 0;
      #endif
  }
};

Ответ 4

Вы можете использовать библиотеку алгоритмов boost string. Его библиотека только заголовка, пока вы не собираетесь делать регулярное выражение. Таким образом, вы можете сделать это очень легко.

http://www.boost.org/doc/libs/1_39_0/doc/html/string_algo.html

Ответ 5

#include <algorithm>
#include <string>
#include <cstdio>


 bool icase_wchar_cmp(wchar_t a, wchar_t b)
{
  return std::toupper(a) == std::toupper(b);
}


bool icase_cmp(std::wstring const& s1, std::wstring const& s2)
{
  return (s1.size() == s2.size()) &&
             std::equal(s1.begin(), s1.end(), s2.begin(),
                              icase_wchar_cmp);
}



int main(int argc, char** argv)
{
  using namespace std;

  wstring str1(L"Hello"), str2(L"hello");

  wprintf(L"%S and %S are %S\n", str1.c_str(), str2.c_str(),
              icase_cmp(str1,str2) ? L"equal" : L"not equal");

  return 0;
}

Ответ 6

Говоря об английском праве?! хотя я бы пошел с моим прекрасным Boost:)

bool isequal(const std::wstring& first, const std::wstring& second)
{
    if(first.size() != second.size())
        return false;

    for(std::wstring::size_type i = 0; i < first.size(); i++)
    {
        if(first[i] != second[i] && first[i] != (second[i] ^ 32))
            return false;
    }

    return true;
}

Ответ 7

Если вам нужно, чтобы строка всегда учитывала нечувствительность к регистру (при использовании операторов == или! =), то возможным элегантным решением является переопределение метода char_traits:: compare.

Определите свою структуру. Пример

struct my_wchar_traits: public std::char_traits< wchar_t>
{
    static int compare( const char_type* op1, const char_type* op2, std::size_t num) 
    {
       // Implementation here... any of the previous responses might help...
    } 
};

Затем определите собственную строку, не учитывающую регистр:

typedef std::basic_string< wchar_t, my_wchar_traits> my_wstring;

Ответ 8

Вы можете использовать mismatch() или lexicographic_compare(). Это предлагается Скоттом Мейерсом в STEP STEP, пункт 35.