web-dev-qa-db-ja.com

大文字と小文字を区別せずにwstringを比較する

これは以前に尋ねられたはずですが、見つかりませんでした。 2つのwstringオブジェクトで大文字と小文字を区別しない比較を行うための組み込みの(つまり、std :: wstringのメソッドまたはアルゴリズムを使用する)方法はありますか?

19
Naveen

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
}
28
Stan

標準ライブラリの使用:

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
}
6
Callum

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
  }
};
3
Chris Harris

ブースト文字列アルゴリズムライブラリを使用できます。正規表現を実行しない限り、そのヘッダーのみのライブラリです。だからあなたはそれをとても簡単に行うことができます。

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

2
Sahas

英語の話でしょ?私は私の素敵なブーストで行きますが:)

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;
}
2
AraK
#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;
}
2
Maik Beckmann

文字列で常に大文字と小文字を区別しない比較を行う必要がある場合(演算子==または!=を使用する場合)、考えられる洗練された解決策は、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;
1