は、私が質問に答えるために
find(vec.begin(), vec.end(), myString) != vec.end())
を使用することができます知っている "VECにMYSTRINGですか?"大文字と小文字を区別した比較を行います。大文字と小文字を区別しない比較が必要です。
位置は重要ではありません。myStringがvecであるかどうかを知りたいだけです。
は、私が質問に答えるために
find(vec.begin(), vec.end(), myString) != vec.end())
を使用することができます知っている "VECにMYSTRINGですか?"大文字と小文字を区別した比較を行います。大文字と小文字を区別しない比較が必要です。
位置は重要ではありません。myStringがvecであるかどうかを知りたいだけです。
あなたは比較を行うためにstd::find_if
、インラインラムダとstd::tolower
を使用することがあります。
//Computing the lower version of mystring
std::string my_string_lower;
my_string_lower.reserve(mystring.size());
std::transform(mystring.begin(), mystring.end(), std::back_inserter(my_string_lower), ::tolower);
// Checking if it is exist in the vector:
auto is_exist = std::find_if(vec.begin(), vec.end(), [&my_string_lower](std::string item){
//Transform the each vector item to lower temporally
std::transform(item.begin(), item.end(), item.begin(), ::tolower);
return mystring==item;
}) != vec.end();
あなたは、文字列の同じvetorに何度も検索しようとしている場合は、一度それを計算した場合、それが良いだろう:
//Computing the lower version of the whole vector
std::vector<std::string> vec_lower;
vec_lower.reserve(vec.size());
std::transform(vec.begin(), vec.end(), std::back_inserter(vec_lower),[](std:string item){
std::transform(item.begin(), item.end(), item.begin(), ::tolower);
return item;
});
//Computing the lower version of mystring
std::string my_string_lower;
my_string_lower.reserve(mystring.size());
std::transform(mystring.begin(), mystring.end(), std::back_inserter(my_string_lower), ::tolower);
// Checking if it is exist in the lower version of the vector:
auto is_exist = std::find_if(vec_lower.begin(), vec_lower.end(), [&my_string_lower](const std::string& item){
return mystring==item;
}) != vec_lower.end();
std::find_if
を使用してカスタムコンパレータを用意する必要があります。大文字と小文字を区別しない比較を達成するには、比較したい両方の文字列を普通の大文字に変換することをお勧めします。
auto ret = std::find_if(vec.begin(), vec.end(),
[&myString](const std::string& s) {
if (s.size() != myString.size())
return false;
return std::equal(s.cbegin(), s.cend(), myString.cbegin(), myString.cend(), [](auto c1, auto c2) { return std::toupper(c1) == std::toupper(c2); });
});
これはmyString
は発生が見つからなかった場合vec.end()
なりますイテレータを返します。それは次のようなコードにつながります。そのイテレーターで何でもできます(文字列が見つかったかどうかを知るためにvec.end()
と比較することを含む)。
ボーナス:Coliru
に最小限の例を実行しているあなたはSTDを使用する必要があります:: TOLOWERとstd :: find_if:
std::vector<std::string> vec = {"ALF", "B"};
std::string toSearch = "Alf";
auto itr = std::find_if(vec.begin(), vec.end(),
[&](auto &s) {
if (s.size() != toSearch.size())
return false;
for (size_t i = 0; i < s.size(); ++i)
if (::tolower(s[i]) == ::tolower(toSearch[i]))
return true;
return false;
}
);
if (itr != vec.end()) {
std::cout << *itr << std::endl;
}
私はこの答えが好きですが...コードは実際には間違っています。修正するには 'if(std :: tolower [s]]!= std :: tolower(newServerName [i])) falseを返します。 return true; ' 比較を変更し、戻り値を入れ替えます。そうでなければ、最初の文字に一致するすべての文字列は等しいと見なされます。 –
あるいは、ずっと小さく、読みやすいためソリューション、Boost!
// #include <algorithm>
// #include <boost/algorithm/string/predicate.hpp>
const auto it = std::find_if(
std::begin(vec),
std::end(vec),
[&myString](const auto& str) { return boost::iequals(myString, str); }
);
const bool found = (it != std::end(vec));
template <class T>
long VecFindIgnoreCase(const std::vector<T>& vec, const std::string& sFind) {
return VecFindIgnoreCase(vec, sFind.c_str());
}
template <class T>
long VecFindIgnoreCase(const std::vector<T>& vec, const char* sFind)
{
for (std::vector<T>::const_iterator iter = vec.begin(); iter != vec.end(); ++iter)
if (_stricmp((*iter).c_str(), sFind) == 0)
return (long)std::distance(vec.begin(), iter);
return -1;
}
template <class T>
long VecFindIgnoreCase(const std::vector<T>& vec, const std::wstring& sFind) {
return VecFindIgnoreCase(vec, sFind.c_str());
}
template <class T>
long VecFindIgnoreCase(const std::vector<T>& vec, const wchar_t* sFind)
{
for (std::vector<T>::const_iterator iter = vec.begin(); iter != vec.end(); ++iter)
if (_wcsicmp((*iter).c_str(), sFind) == 0)
return (long)std::distance(vec.begin(), iter);
return -1;
}
用途:
#include <string>
#include <vector>
void TestCode()
{
std::vector<std::string> strvecA;
std::vector<std::wstring> strvecW;
strvecA.push_back("abc");
strvecA.push_back("def");
strvecA.push_back("ghi");
strvecW.push_back(L"abc");
strvecW.push_back(L"def");
strvecW.push_back(L"ghi");
long ind;
ind = VecFindIgnoreCase(strvecA, "ABC"); // ind = 0 found
ind = VecFindIgnoreCase(strvecA, "ghI"); // ind = 2 found
ind = VecFindIgnoreCase(strvecA, "Xyz"); // ind = -1 not found
ind = VecFindIgnoreCase(strvecW, L"aBc"); // ind = 0 found
ind = VecFindIgnoreCase(strvecW, L"DEF"); // ind = 1 found
ind = VecFindIgnoreCase(strvecW, L"xyZ"); // ind = -1 not found
std::string sFind("mno");
if ((ind = VecFindIgnoreCase(strvecA, sFind)) >= 0) {
// found at strvecA[ind]
} else {
// not found
}
}
コードが何をしているか十分な説明をしてください – Ibo
は、このトリックを行う必要がありますか? [ここにリンクの説明を入力してください](http://stackoverflow.com/questions/14322299/c-stdfind-with-a-custom-comparator) – tomascapek
[関連する質問](https://stackoverflow.com/questions/11635/case -insensitive-string-comparison-in-c)を使用します。 – jotik