C++ std:: string start_with / end_with версии без учета регистра?
В C++20 в std::string добавлены start_with, end_with.
Есть хороший способ, чтобы заставить его быть случай в чувствительный?
Обратите внимание, что производительность имеет значение, поэтому я не хочу, чтобы обе строки (или std::min(len1, len2)
части из них).
В отличие от обычных <algorithm>
алгоритмы starts_with
не имеет перегрузки с компаратором, поэтому я не вижу хорошего способа сделать это.
И я как бы понимаю, что 90+% случаев чувствительны к регистру, и что член fns в C++ избегается, если только он не является чрезвычайно полезным... поэтому я знаю, почему существует это ограничение, мне просто любопытно, можно ли что-то относительно читабельное можно взломать вместе С ++20 без моего ручного вызова std::equal(или равных диапазонов) с настраиваемым компаратором.
3 ответа
Я тоже недавно столкнулся с этой проблемой.
Если вы не возражаете против использования boost, есть функции istarts_with и iends_with .
Они делают именно то, что вам нужно.
Мне было любопытно посмотреть, как работает предложение применить этот ответ. Вот результат.
Код из указанного ответа:
struct ci_char_traits : public char_traits<char> { static bool eq(char c1, char c2) { return toupper(c1) == toupper(c2); } static bool ne(char c1, char c2) { return toupper(c1) != toupper(c2); } static bool lt(char c1, char c2) { return toupper(c1) < toupper(c2); } static int compare(const char* s1, const char* s2, size_t n) { while( n-- != 0 ) { if( toupper(*s1) < toupper(*s2) ) return -1; if( toupper(*s1) > toupper(*s2) ) return 1; ++s1; ++s2; } return 0; } static const char* find(const char* s, int n, char a) { while( n-- > 0 && toupper(*s) != toupper(a) ) { ++s; } return s; } }; typedef std::basic_string<char, ci_char_traits> ci_string;
Там ответ предлагал использовать ci_string
вместо того std::string
. Здесь мы просто хотим создатьci_views
к std::string
s:
typedef std::basic_string_view<char, ci_char_traits> ci_string_view;
int main()
{
std::string x{"ABCD"};
std::string y{"abcd"};
std::cout << ci_string_view{x.begin(),x.end()}.ends_with(ci_string_view{y.begin(),y.end()});
}
Выход:
1
std::mismatch(s1.begin(), s1.end(), s2.begin(), s2.end(), <comparator>)
буду делать то, что ты хочешь. Вы должны написать компаратор без учета регистра, но я уверен, что вы сможете это понять.