C++中的std :: string是否有内置函数,当字符串可以是大写或小写时,按字母顺序比较两个字符串?

Wor*_*hot 7 c++ string case-insensitive

我知道对于C++来说,如果两个单词都是完全较低或完全是大写的话,那么基本的比较运算符就可以完成任务.我有一个字符串数组,字母可以从低到高不等.这是我可以使用的字符串的一个小问题:

"丰富的生活CH"

"新生活WMN MNSTRY"

"新生活大会"

我知道在Java中存在函数String.compareToIgnoreCase().这个函数有C++等价吗?

小智 8

我不知道标准库中的任何不区分大小写的函数,但您可以为以下内容指定自定义谓词std::equal:

std::string a("hello");
std::string b("HELLO");
std::cout << std::equal(a.begin(), a.end(), b.begin(),
    [] (const char& a, const char& b)
    {
        return (std::tolower(a) == std::tolower(b));
    });
Run Code Online (Sandbox Code Playgroud)

有关将区域设置考虑在内的解决方案,请参阅不区分大小写的std :: string.find().

#include <locale>

template<typename charT = std::string::value_type>
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_;
};

int main()
{
    std::string a("hello");
    std::string b("HELLO");
    std::cout << std::equal(a.begin(), a.end(), b.begin(),
        my_equal<>(std::locale()));
}
Run Code Online (Sandbox Code Playgroud)


Bar*_*rry 5

是的,有一种不区分大小写的方式可以比较C ++中的字符串。关键是std::string模板:

template <class charT,
          class traits = char_traits<charT>,
          class Allocator = allocator<charT>>
class basic_string;
Run Code Online (Sandbox Code Playgroud)

traits这里控制如何charT的相互关系。对于normal std::string,它们会执行您期望的操作,但是我们可以编写不区分大小写的自己的特征:

struct case_insensitive_traits
: char_traits<char>
{
    static bool eq(char a, char b) { return tolower(a) == tolower(b); }
    static bool ne(char a, char b) { return !eq(a, b); }
    static bool lt(char a, char b) { return tolower(a) < tolower(b); }
    static bool gt(char a, char b) { return tolower(a) > tolower(b); }

    static int compare(const char* a, const char* b, size_t n)
    {
        for (size_t i = 0; i < n; ++i) {
            int delta = tolower(a[i]) - tolower(b[i]);
            if (delta != 0) return delta;
        }
        return 0;
    }

    static const char* find(const char* s, size_t n, char c)
    {
        c = tolower(c);
        for (size_t i = 0; i < n; ++i, ++s) {
            if (tolower(*s) == c) return s;
        }
        return nullptr;
    }
};
Run Code Online (Sandbox Code Playgroud)

接着就,随即:

using case_insensitive_string = std::basic_string<char, case_insensitive_traits>;

case_insensitive_string a{"hello"};
case_insensitive_string b{"hElLo"};

assert(a == b);
Run Code Online (Sandbox Code Playgroud)