1. ホーム
  2. c++

大文字小文字を区別しない std::string.find()

2023-09-04 18:08:20

質問

私は std::string 's find() メソッドを使って、ある文字列が別の文字列の部分文字列であるかどうかをテストしています。今、私は同じことの大文字小文字を区別しないバージョンが必要です。文字列の比較のために、私はいつでも stricmp() を使うことができますが stristr() .

様々な回答を見つけましたが、ほとんどの場合 Boost を使うことを勧めていますが、私の場合、それはオプションではありません。 さらに、私は std::wstring / wchar_t . 何かアイデアはありますか?

どのように解決するのですか?

あなたは std::search をカスタム述語で使うことができます。

#include <locale>
#include <iostream>
#include <algorithm>
using namespace std;

// templated version of my_equal so it could work with both char and wchar_t
template<typename charT>
struct my_equal {
    my_equal( const std::locale& loc ) : loc_(loc) {}
    bool operator()(charT ch1, charT ch2) {
        return std::toupper(ch1, loc_) == std::toupper(ch2, loc_);
    }
private:
    const std::locale& loc_;
};

// find substring (case insensitive)
template<typename T>
int ci_find_substr( const T& str1, const T& str2, const std::locale& loc = std::locale() )
{
    typename T::const_iterator it = std::search( str1.begin(), str1.end(), 
        str2.begin(), str2.end(), my_equal<typename T::value_type>(loc) );
    if ( it != str1.end() ) return it - str1.begin();
    else return -1; // not found
}

int main(int arc, char *argv[]) 
{
    // string test
    std::string str1 = "FIRST HELLO";
    std::string str2 = "hello";
    int f1 = ci_find_substr( str1, str2 );

    // wstring test
    std::wstring wstr1 = L"ОПЯТЬ ПРИВЕТ";
    std::wstring wstr2 = L"привет";
    int f2 = ci_find_substr( wstr1, wstr2 );

    return 0;
}