文字列比較について質問があります。
英語文字列同士を比較して、
同一かどうか判定する処理を作成しています。
ただし、大文字小文字のみの違いなら
一致していると判定したいです。
現在はC共通関数_stricmp()を使用し
以下のようにしています。
std::string str1 = ABCDE;
std::string str2 = abcde;
if(_stricmp(str1.c_str(),str2.c_str()) == 0)
{
// 同じ文字列
}
これと同等のことを、
STLのみで行うことはできるのでしょうか?
単純な実装だと例えばこんなのとか。
namespace foo {
int
stricmp(std::string lhs, std::string rhs)
{
// 小文字に変換してから比較
std::transform(lhs.begin(), lhs.end(), lhs.begin(), std::tolower);
std::transform(rhs.begin(), rhs.end(), rhs.begin(), std::tolower);
return lhs.compare(rhs);
}
}
変換が無駄でいやだと思うなら、std::equal で比較関数を書けばよいと思います。
こんなんでいいのかしら?
#include <string>
#include <iostream>
#include <algorithm>
#include <locale>
struct equal_char_ignorecase {
bool operator()(char x, char y) const {
std::locale loc;
return std::tolower(x,loc) == std::tolower(y,loc);
}
};
bool icomp(const std::string& x, const std::string& y) {
return x.size() == y.size() &&
std::equal(x.begin(), x.end(), y.begin(), equal_char_ignorecase());
}
int main() {
std::cout << (icomp(Hello,hElLo) ? same : different) << std::endl;
}
ご返事ありがとうございます。
大文字小文字の一致も含めて判定する場合は、
以下のようにしているので、
std::string str1 = ABCDE;
std::string str2 = abcde;
if(str1.compare(str2) == 0)
{
// 同じ文字列
}
if(str1 == str2)
{
// 同じ文字列
}
大文字小文字の一致を無視する場合も
STLのみですっきりコーディングできないかと
思い質問してみました。
_stricmp()の方がすっきりしそうなので、
これで行ってみます。
でも以下とか普段使わないので、
用法が勉強になりました。
std::tolower(), std::equal()
ありがとうございました。
> 大文字小文字の一致を無視する場合もSTLのみですっきりコーディングできないかと
> 思い質問してみました。
> _stricmp()の方がすっきりしそうなので、これで行ってみます。
例えば私のやつを最初のsunyopuさんの形式にあわせるとこんな感じになります。
if(foo::stricmp(str1,str2) == 0)
{
// 同じ文字列
}
επιστημηさんのものだとこんな感じ。
if(icomp(str1,str2))
{
// 同じ文字列
}
「すっきり」の基準は呼ぶ側でなく、自分で実装するか否かということでしょうか。
VC専用で言語標準以外の機能を使ってもいいなら、
_stricmp 使うと何の実装に必要がない分だけ確かに楽だと思います。
そうでないなら、直接 _stricmp を使わずにラッパーなりを書くのでしょうから、
結局大差ないような気もします。
inline int my_stricmp(......){ return ::_stricmp(.......); }