1

C++20 将starts_with、 ends_with 添加到 std::string。

有没有一种很好的方法让它区分大小写?

请注意,性能很重要,所以我不想将两个字符串(或std::min(len1, len2)其中的一部分)都小写/大写。

与常规<algorithm>算法不同starts_with,比较器没有过载,所以我看不到这样做的好方法。

而且我有点理解 90+% 的情况是区分大小写的,除非非常有用,否则 C++ 中的成员 fns 会被避免......所以我知道为什么存在这个限制,我只是好奇是否可以将相对可读的东西一起破解C++20 没有我用自定义比较器手动调用 std::equal(或范围版本)。

4

3 回答 3

2

我很想知道应用这个答案的建议是如何产生的。这就是结果。

来自上述答案的代码:

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_viewsto std::strings:

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

现场示例

于 2020-09-02T19:33:31.083 回答
1

std::mismatch(s1.begin(), s1.end(), s2.begin(), s2.end(), <comparator>)会做你想做的。您必须编写不区分大小写的比较器,但我相信您可以弄清楚。

于 2020-09-12T16:57:17.257 回答
1

我最近也遇到了这个问题。

如果你不介意使用 boost,还有istarts_withiends_with函数。

他们完全按照您的需要做。

于 2021-02-06T07:30:53.257 回答