Zeichenkettenvergleich ohne Berücksichtigung der Groß- und Kleinschreibung in C++ [geschlossen]

StackOverflow https://stackoverflow.com/questions/11635

  •  08-06-2019
  •  | 
  •  

Frage

Was ist die beste Möglichkeit, in C++ einen Zeichenfolgenvergleich ohne Berücksichtigung der Groß- und Kleinschreibung durchzuführen, ohne eine Zeichenfolge vollständig in Groß- oder Kleinbuchstaben umzuwandeln?

Bitte geben Sie an, ob die Methoden Unicode-freundlich sind und wie portierbar sie sind.

War es hilfreich?

Lösung

Boost enthält hierfür einen praktischen Algorithmus:

#include <boost/algorithm/string.hpp>
// Or, for fewer header dependencies:
//#include <boost/algorithm/string/predicate.hpp>

std::string str1 = "hello, world!";
std::string str2 = "HELLO, WORLD!";

if (boost::iequals(str1, str2))
{
    // Strings are identical
}

Andere Tipps

Profitieren Sie vom Standard char_traits.Denken Sie daran, dass a std::string ist in der Tat eine Typdefinition für std::basic_string<char>, oder genauer gesagt, std::basic_string<char, std::char_traits<char> >.Der char_traits Typ beschreibt, wie Charaktere verglichen werden, wie sie kopieren, wie sie wirken usw.Sie müssen lediglich eine neue Zeichenfolge eingeben basic_string, und versehen Sie es mit Ihren eigenen Wünschen char_traits die Groß- und Kleinschreibung ohne Berücksichtigung vergleichen.

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;

Die Details liegen vor Guru der Woche Nummer 29.

Das Problem mit Boost besteht darin, dass Sie sich mit Boost verknüpfen und von ihm abhängig sein müssen.In manchen Fällen nicht einfach (z.B.Android).

Und die Verwendung von char_traits bedeutet alle Bei Ihren Vergleichen wird die Groß-/Kleinschreibung nicht beachtet, was normalerweise nicht das ist, was Sie wollen.

Das sollte ausreichen.Es sollte einigermaßen effizient sein.Kommt jedoch nicht mit Unicode oder ähnlichem zurecht.

bool iequals(const string& a, const string& b)
{
    unsigned int sz = a.size();
    if (b.size() != sz)
        return false;
    for (unsigned int i = 0; i < sz; ++i)
        if (tolower(a[i]) != tolower(b[i]))
            return false;
    return true;
}

Aktualisieren:Bonus-C++14-Version (#include <algorithm>):

bool iequals(const string& a, const string& b)
{
    return std::equal(a.begin(), a.end(),
                      b.begin(), b.end(),
                      [](char a, char b) {
                          return tolower(a) == tolower(b);
                      });
}

Wenn Sie sich auf einem POSIX-System befinden, können Sie verwenden strcasecmp.Diese Funktion ist jedoch weder Bestandteil von Standard-C noch unter Windows verfügbar.Dadurch wird ein Vergleich ohne Berücksichtigung der Groß-/Kleinschreibung für 8-Bit-Zeichen durchgeführt, solange das Gebietsschema POSIX ist.Wenn das Gebietsschema nicht POSIX ist, sind die Ergebnisse undefiniert (es kann also ein lokalisierter Vergleich durchgeführt werden oder auch nicht).Ein Breitzeichen-Äquivalent ist nicht verfügbar.

Andernfalls verfügen viele historische C-Bibliotheksimplementierungen über die Funktionen stricmp() und strnicmp().Visual C++ unter Windows hat alle diese Namen umbenannt, indem ihnen ein Unterstrich vorangestellt wurde, da sie nicht Teil des ANSI-Standards sind, weshalb sie auf diesem System so genannt werden _stricmp oder _strnicmp.Einige Bibliotheken verfügen möglicherweise auch über Wide-Character- oder Multibyte-äquivalente Funktionen (normalerweise mit dem Namen z. B.wcsicmp, mbcsicmp usw.).

Sowohl C als auch C++ sind sich der Internationalisierungsprobleme weitgehend nicht bewusst, daher gibt es keine gute Lösung für dieses Problem, außer die Verwendung einer Bibliothek eines Drittanbieters.Kasse IBM ICU (Internationale Komponenten für Unicode) wenn Sie eine robuste Bibliothek für C/C++ benötigen.ICU ist sowohl für Windows- als auch für Unix-Systeme geeignet.

Sprechen Sie über einen dummen Vergleich ohne Berücksichtigung der Groß- und Kleinschreibung oder einen vollständig normalisierten Unicode-Vergleich?

Bei einem dummen Vergleich werden keine Zeichenfolgen gefunden, die möglicherweise gleich sind, aber nicht binär gleich sind.

Beispiel:

U212B (ANGSTROM SIGN)
U0041 (LATIN CAPITAL LETTER A) + U030A (COMBINING RING ABOVE)
U00C5 (LATIN CAPITAL LETTER A WITH RING ABOVE).

Sind alle gleichwertig, haben aber auch unterschiedliche binäre Darstellungen.

Das gesagt, Unicode-Normalisierung sollte eine Pflichtlektüre sein, insbesondere wenn Sie Hangul, Thailändisch und andere asiatische Sprachen unterstützen möchten.

Außerdem hat IBM die meisten optimierten Unicode-Algorithmen weitgehend patentieren lassen und sie öffentlich zugänglich gemacht.Sie unterhalten auch eine Implementierung: IBM-Intensivstation

boost::iequals ist im Fall von Zeichenfolgen nicht utf-8-kompatibel.Sie können verwenden boost::locale.

comparator<char,collator_base::secondary> cmpr;
cout << (cmpr(str1, str2) ? "str1 < str2" : "str1 >= str2") << endl;
  • Primär – Akzente und Groß-/Kleinschreibung ignorieren, nur Grundbuchstaben vergleichen.Beispielsweise sind „Fassade“ und „Fassade“ dasselbe.
  • Sekundär: Ignorieren Sie die Groß-/Kleinschreibung, berücksichtigen Sie jedoch Akzente.„Fassade“ und „Fassade“ sind unterschiedlich, aber „Fassade“ und „Fassade“ sind dasselbe.
  • Tertiär – Groß-/Kleinschreibung und Akzente berücksichtigen:„Fassade“ und „Fassade“ sind unterschiedlich.Interpunktion ignorieren.
  • Quartär – Groß-/Kleinschreibung, Akzente und Zeichensetzung berücksichtigen.Die Wörter müssen hinsichtlich der Unicode-Darstellung identisch sein.
  • Identisch – wie quaternär, aber auch Codepunkte vergleichen.

Mein erster Gedanke für eine Nicht-Unicode-Version war, so etwas zu tun:


bool caseInsensitiveStringCompare(const string& str1, const string& str2) {
    if (str1.size() != str2.size()) {
        return false;
    }
    for (string::const_iterator c1 = str1.begin(), c2 = str2.begin(); c1 != str1.end(); ++c1, ++c2) {
        if (tolower(*c1) != tolower(*c2)) {
            return false;
        }
    }
    return true;
}

Sie können verwenden strcasecmp unter Unix, bzw stricmp unter Windows.

Was bisher noch nicht erwähnt wurde: Wenn Sie STL-Strings mit diesen Methoden verwenden, ist es sinnvoll, zunächst die Länge der beiden Strings zu vergleichen, da Ihnen diese Informationen bereits in der String-Klasse zur Verfügung stehen.Dies könnte den kostspieligen String-Vergleich verhindern, wenn die beiden Strings, die Sie vergleichen, von vornherein nicht einmal die gleiche Länge haben.

Visual C++-Stringfunktionen, die Unicode unterstützen: http://msdn.microsoft.com/en-us/library/cc194799.aspx

das, nach dem Sie wahrscheinlich suchen, ist _wcsnicmp

Ich versuche, aus allen Beiträgen eine gute Antwort zusammenzubasteln, also helfen Sie mir, dies zu bearbeiten:

Hier ist eine Methode, dies zu tun. Obwohl sie die Zeichenfolgen transformiert und nicht Unicode-freundlich ist, sollte sie portierbar sein, was ein Pluspunkt ist:

bool caseInsensitiveStringCompare( const std::string& str1, const std::string& str2 ) {
    std::string str1Cpy( str1 );
    std::string str2Cpy( str2 );
    std::transform( str1Cpy.begin(), str1Cpy.end(), str1Cpy.begin(), ::tolower );
    std::transform( str2Cpy.begin(), str2Cpy.end(), str2Cpy.begin(), ::tolower );
    return ( str1Cpy == str2Cpy );
}

Nach dem, was ich gelesen habe, ist dies portabler als stricmp(), da stricmp() tatsächlich nicht Teil der Standardbibliothek ist, sondern nur von den meisten Compiler-Anbietern implementiert wird.

Um eine wirklich Unicode-freundliche Implementierung zu erhalten, müssen Sie anscheinend die Standardbibliothek verlassen.Eine gute Bibliothek von Drittanbietern ist die IBM ICU (Internationale Komponenten für Unicode)

Auch boost::iequals bietet ein ziemlich gutes Hilfsmittel für diese Art von Vergleich.

Der Boost.String Die Bibliothek verfügt über viele Algorithmen für Vergleiche ohne Berücksichtigung der Groß- und Kleinschreibung usw.

Sie könnten Ihr eigenes implementieren, aber warum sollten Sie sich die Mühe machen, wenn es bereits fertig ist?

Zu Ihrer Information, strcmp() Und stricmp() sind anfällig für einen Pufferüberlauf, da sie nur so lange verarbeiten, bis sie auf einen Nullterminator treffen.Es ist sicherer zu verwenden _strncmp() Und _strnicmp().

Für meine grundlegenden Anforderungen an den String-Vergleich ohne Berücksichtigung der Groß-/Kleinschreibung möchte ich weder eine externe Bibliothek verwenden, noch möchte ich eine separate String-Klasse mit Merkmalen ohne Berücksichtigung der Groß-/Kleinschreibung, die mit allen meinen anderen Strings inkompatibel ist.

Also, was ich mir ausgedacht habe, ist Folgendes:

bool icasecmp(const string& l, const string& r)
{
    return l.size() == r.size()
        && equal(l.cbegin(), l.cend(), r.cbegin(),
            [](string::value_type l1, string::value_type r1)
                { return toupper(l1) == toupper(r1); });
}

bool icasecmp(const wstring& l, const wstring& r)
{
    return l.size() == r.size()
        && equal(l.cbegin(), l.cend(), r.cbegin(),
            [](wstring::value_type l1, wstring::value_type r1)
                { return towupper(l1) == towupper(r1); });
}

Eine einfache Funktion mit einer Überladung für char und einer anderen für whar_t.Verwendet nichts Ungewöhnliches und sollte daher auf jeder Plattform funktionieren.

Beim Gleichheitsvergleich werden Probleme wie Codierung mit variabler Länge und Unicode-Normalisierung nicht berücksichtigt, aber basic_string unterstützt das ohnehin nicht, was mir bekannt ist, und es ist normalerweise kein Problem.

In Fällen, in denen eine anspruchsvollere lexikografische Manipulation des Textes erforderlich ist, müssen Sie einfach eine Drittanbieterbibliothek wie Boost verwenden, was zu erwarten ist.

std::equal(str1.begin(), str1.end(), str2.begin(), [](auto a, auto b){return std::tolower(a)==std::tolower(b);})

Sie können den obigen Code in C++14 verwenden, wenn Sie Boost nicht verwenden können.Sie müssen verwenden std::towlower für breite Zeichen.

Kurz und schön.Keine anderen Abhängigkeiten als erweitert std C lib.

strcasecmp(str1.c_str(), str2.c_str()) == 0

kehrt zurück WAHR Wenn str1 Und str2 sind gleich.strcasecmp möglicherweise nicht vorhanden, es könnte Analoga geben stricmp, strcmpi, usw.

Beispielcode:

#include <iostream>
#include <string>
#include <string.h> //For strcasecmp(). Also could be found in <mem.h>

using namespace std;

/// Simple wrapper
inline bool str_ignoreCase_cmp(std::string const& s1, std::string const& s2) {
    if(s1.length() != s2.length())
        return false;  // optimization since std::string holds length in variable.
    return strcasecmp(s1.c_str(), s2.c_str()) == 0;
}

/// Function object - comparator
struct StringCaseInsensetiveCompare {
    bool operator()(std::string const& s1, std::string const& s2) {
        if(s1.length() != s2.length())
            return false;  // optimization since std::string holds length in variable.
        return strcasecmp(s1.c_str(), s2.c_str()) == 0;
    }
    bool operator()(const char *s1, const char * s2){ 
        return strcasecmp(s1,s2)==0;
    }
};


/// Convert bool to string
inline char const* bool2str(bool b){ return b?"true":"false"; }

int main()
{
    cout<< bool2str(strcasecmp("asd","AsD")==0) <<endl;
    cout<< bool2str(strcasecmp(string{"aasd"}.c_str(),string{"AasD"}.c_str())==0) <<endl;
    StringCaseInsensetiveCompare cmp;
    cout<< bool2str(cmp("A","a")) <<endl;
    cout<< bool2str(cmp(string{"Aaaa"},string{"aaaA"})) <<endl;
    cout<< bool2str(str_ignoreCase_cmp(string{"Aaaa"},string{"aaaA"})) <<endl;
    return 0;
}

Ausgabe:

true
true
true
true
true

Sehen std::lexicographical_compare:

// lexicographical_compare example
#include <iostream>  // std::cout, std::boolalpha
#include <algorithm>  // std::lexicographical_compare
#include <cctype>  // std::tolower

// a case-insensitive comparison function:
bool mycomp (char c1, char c2) {
    return std::tolower(c1)<std::tolower(c2);
}

int main () {
    char foo[] = "Apple";
    char bar[] = "apartment";

    std::cout << std::boolalpha;

    std::cout << "Comparing foo and bar lexicographically (foo < bar):\n";

    std::cout << "Using default comparison (operator<): ";
    std::cout << std::lexicographical_compare(foo, foo + 5, bar, bar + 9);
    std::cout << '\n';

    std::cout << "Using mycomp as comparison object: ";
    std::cout << std::lexicographical_compare(foo, foo + 5, bar, bar + 9, mycomp);
    std::cout << '\n';

    return 0;
}

Demo

Angenommen, Sie suchen nach einer Methode und nicht nach einer magischen Funktion, die bereits existiert, gibt es ehrlich gesagt keinen besseren Weg.Wir könnten alle mit cleveren Tricks Codeschnipsel für begrenzte Zeichensätze schreiben, aber am Ende des Tages muss man die Zeichen irgendwann umwandeln.

Der beste Ansatz für diese Konvertierung besteht darin, dies vor dem Vergleich zu tun.Dies ermöglicht Ihnen ein hohes Maß an Flexibilität, wenn es um Codierungsschemata geht, die Ihr tatsächlicher Vergleichsoperator nicht kennen dürfte.

Sie können diese Konvertierung natürlich hinter Ihrer eigenen String-Funktion oder Klasse „verstecken“, aber Sie müssen die Strings vor dem Vergleich trotzdem konvertieren.

Ich habe eine Version von char_traits geschrieben, bei der die Groß-/Kleinschreibung nicht beachtet wird, um sie mit std::basic_string zu verwenden, um einen std::string zu generieren, bei dem die Groß-/Kleinschreibung nicht beachtet wird, wenn Vergleiche, Suchvorgänge usw. mithilfe der integrierten std::basic_string-Memberfunktionen durchgeführt werden.

Mit anderen Worten, ich wollte so etwas machen.

std::string a = "Hello, World!";
std::string b = "hello, world!";

assert( a == b );

...was std::string nicht verarbeiten kann.Hier ist die Verwendung meiner neuen char_traits:

std::istring a = "Hello, World!";
std::istring b = "hello, world!";

assert( a == b );

...und hier ist die Umsetzung:

/*  ---

        Case-Insensitive char_traits for std::string's

        Use:

            To declare a std::string which preserves case but ignores case in comparisons & search,
            use the following syntax:

                std::basic_string<char, char_traits_nocase<char> > noCaseString;

            A typedef is declared below which simplifies this use for chars:

                typedef std::basic_string<char, char_traits_nocase<char> > istring;

    --- */

    template<class C>
    struct char_traits_nocase : public std::char_traits<C>
    {
        static bool eq( const C& c1, const C& c2 )
        { 
            return ::toupper(c1) == ::toupper(c2); 
        }

        static bool lt( const C& c1, const C& c2 )
        { 
            return ::toupper(c1) < ::toupper(c2);
        }

        static int compare( const C* s1, const C* s2, size_t N )
        {
            return _strnicmp(s1, s2, N);
        }

        static const char* find( const C* s, size_t N, const C& a )
        {
            for( size_t i=0 ; i<N ; ++i )
            {
                if( ::toupper(s[i]) == ::toupper(a) ) 
                    return s+i ;
            }
            return 0 ;
        }

        static bool eq_int_type( const int_type& c1, const int_type& c2 )
        { 
            return ::toupper(c1) == ::toupper(c2) ; 
        }       
    };

    template<>
    struct char_traits_nocase<wchar_t> : public std::char_traits<wchar_t>
    {
        static bool eq( const wchar_t& c1, const wchar_t& c2 )
        { 
            return ::towupper(c1) == ::towupper(c2); 
        }

        static bool lt( const wchar_t& c1, const wchar_t& c2 )
        { 
            return ::towupper(c1) < ::towupper(c2);
        }

        static int compare( const wchar_t* s1, const wchar_t* s2, size_t N )
        {
            return _wcsnicmp(s1, s2, N);
        }

        static const wchar_t* find( const wchar_t* s, size_t N, const wchar_t& a )
        {
            for( size_t i=0 ; i<N ; ++i )
            {
                if( ::towupper(s[i]) == ::towupper(a) ) 
                    return s+i ;
            }
            return 0 ;
        }

        static bool eq_int_type( const int_type& c1, const int_type& c2 )
        { 
            return ::towupper(c1) == ::towupper(c2) ; 
        }       
    };

    typedef std::basic_string<char, char_traits_nocase<char> > istring;
    typedef std::basic_string<wchar_t, char_traits_nocase<wchar_t> > iwstring;

Dies ohne Verwendung von Boost kann erreicht werden, indem der C-String-Zeiger mit abgerufen wird c_str() und nutzen strcasecmp:

std::string str1 ="aBcD";
std::string str2 = "AbCd";;
if (strcasecmp(str1.c_str(), str2.c_str()) == 0)
{
    //case insensitive equal 
}

Ich habe gute Erfahrungen damit gemacht Internationale Komponenten für Unicode-Bibliotheken - Sie sind äußerst leistungsstark und bieten Methoden zur Konvertierung, zur Unterstützung von Gebietsschemata, zum Rendern von Datum und Uhrzeit, zur Fallzuordnung (was Sie anscheinend nicht wollen) und Kollation, einschließlich Vergleich ohne Berücksichtigung von Groß- und Kleinschreibung (und mehr).Ich habe nur die C++-Version der Bibliotheken verwendet, es scheint aber auch eine Java-Version zu geben.

Es gibt Methoden zum Durchführen normalisierter Vergleiche, auf die sich @Coincoin bezieht, und die sogar das Gebietsschema berücksichtigen können – zum Beispiel (und dies ist ein Sortierbeispiel, keine strenge Gleichheit), traditionell im Spanischen (in Spanien) wird mit der Buchstabenkombination „ll“ zwischen sortiert „l“ und „m“, also „lz“ < „ll“ < „ma“.

Benutz einfach strcmp() für Groß-/Kleinschreibung und strcmpi() oder stricmp() zum Vergleich ohne Berücksichtigung der Groß- und Kleinschreibung.Welche sind beide in der Header-Datei <string.h>

Format:

int strcmp(const char*,const char*);    //for case sensitive
int strcmpi(const char*,const char*);   //for case insensitive

Verwendung:

string a="apple",b="ApPlE",c="ball";
if(strcmpi(a.c_str(),b.c_str())==0)      //(if it is a match it will return 0)
    cout<<a<<" and "<<b<<" are the same"<<"\n";
if(strcmpi(a.c_str(),b.c_str()<0)
    cout<<a[0]<<" comes before ball "<<b[0]<<", so "<<a<<" comes before "<<b;

Ausgabe

Apple und Apple sind dasselbe

a kommt vor b, also kommt der Apfel vor dem Ball

Nur eine Anmerkung dazu, für welche Methode Sie sich letztendlich entscheiden, falls diese Methode die Verwendung von beinhaltet strcmp dass einige Antworten darauf hindeuten:

strcmp funktioniert im Allgemeinen nicht mit Unicode-Daten.Im Allgemeinen funktioniert es seitdem nicht einmal mit bytebasierten Unicode-Codierungen wie utf-8 strcmp Führt nur Byte-für-Byte-Vergleiche durch und in utf-8 codierte Unicode-Codepunkte können mehr als 1 Byte beanspruchen.Der einzige spezifische Unicode-Fall strcmp Wenn eine mit einer bytebasierten Kodierung kodierte Zeichenfolge nur Codepunkte unter U+00FF enthält, reicht ein Byte-pro-Byte-Vergleich aus.

Seit Anfang 2013 ist das von IBM betreute ICU-Projekt eine ziemlich gute Antwort darauf.

http://site.icu-project.org/

Die ICU ist eine "vollständige, tragbare Unicode -Bibliothek, die die Industriestandards genau verfolgt". Für das spezifische Problem des String -Vergleichs tut das Kollationsobjekt das, was Sie wollen.

Das Mozilla-Projekt hat Mitte 2012 ICU für die Internationalisierung in Firefox übernommen;Sie können die technische Diskussion, einschließlich Fragen zu Build-Systemen und Datendateigröße, hier verfolgen:

Zu spät zur Party, aber hier ist eine Variante, die funktioniert std::locale, und behandelt somit Türkisch korrekt:

auto tolower = std::bind1st(
    std::mem_fun(
        &std::ctype<char>::tolower),
    &std::use_facet<std::ctype<char> >(
        std::locale()));

gibt Ihnen einen Funktor, der das aktive Gebietsschema verwendet, um Zeichen in Kleinbuchstaben umzuwandeln, die Sie dann über verwenden können std::transform So generieren Sie Zeichenfolgen in Kleinbuchstaben:

std::string left = "fOo";
transform(left.begin(), left.end(), left.begin(), tolower);

Das funktioniert auch für wchar_t basierende Zeichenfolgen.

Es sieht so aus, als würden die oben genannten Lösungen die Vergleichsmethode nicht verwenden und „total“ nicht erneut implementieren. Hier ist meine Lösung und ich hoffe, dass sie für Sie funktioniert (sie funktioniert einwandfrei).

#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
string tolow(string a)
{
    for(unsigned int i=0;i<a.length();i++)
    {
        a[i]=tolower(a[i]);
    }
    return a;
}
int main()
{
    string str1,str2;
    cin>>str1>>str2;
    int temp=tolow(str1).compare(tolow(str2));
    if(temp>0)
        cout<<1;
    else if(temp==0)
        cout<<0;
    else
        cout<<-1;
}

Wenn Sie es nicht verwenden möchten Boost-Bibliothek Dann ist hier eine Lösung dafür, bei der nur der C++-Standard-IO-Header verwendet wird.

#include <iostream>

struct iequal
{
    bool operator()(int c1, int c2) const
    {
        // case insensitive comparison of two characters.
        return std::toupper(c1) == std::toupper(c2);
    }
};

bool iequals(const std::string& str1, const std::string& str2)
{
    // use std::equal() to compare range of characters using the functor above.
    return std::equal(str1.begin(), str1.end(), str2.begin(), iequal());
}

int main(void)
{
    std::string str_1 = "HELLO";
    std::string str_2 = "hello";

    if(iequals(str_1,str_2))
    {
        std::cout<<"String are equal"<<std::endl;   
    }

    else
    {
        std::cout<<"String are not equal"<<std::endl;
    }


    return 0;
}

Wenn Sie einen Vektor mit Zeichenfolgen haben, zum Beispiel:

std::sort(std::begin(myvector), std::end(myvector), [](std::string const &a, std::string const &b)
{
    return std::lexicographical_compare(std::begin(a), std::end(a), std::begin(b), std::end(b), [](std::string::value_type a, std::string::value_type b)
    {
        return std::tolower(a) < std::tolower(b); //case-insensitive
    });
});

http://ideone.com/N6sq6X

Wenn Sie einen Quellstring häufiger mit anderen Strings vergleichen müssen, ist die Verwendung von Regex eine elegante Lösung.

std::wstring first = L"Test";
std::wstring second = L"TEST";

std::wregex pattern(first, std::wregex::icase);
bool isEqual = std::regex_match(second, pattern);

Eine einfache Möglichkeit, zwei Zeichenfolgen in C++ zu vergleichen (getestet für Windows), ist die Verwendung von _stricmp

// Case insensitive (could use equivalent _stricmp)  
result = _stricmp( string1, string2 );  

Wenn Sie mit std::string verwenden möchten, ein Beispiel:

std::string s1 = string("Hello");
if ( _stricmp(s1.c_str(), "HELLO") == 0)
   std::cout << "The string are equals.";

Weitere Informationen finden Sie hier: https://msdn.microsoft.com/it-it/library/e0z9k731.aspx

bool insensitive_c_compare(char A, char B){
  static char mid_c = ('Z' + 'a') / 2 + 'Z';
  static char up2lo = 'A' - 'a'; /// the offset between upper and lowers

  if ('a' >= A and A >= 'z' or 'A' >= A and 'Z' >= A)
      if ('a' >= B and B >= 'z' or 'A' >= B and 'Z' >= B)
      /// check that the character is infact a letter
      /// (trying to turn a 3 into an E would not be pretty!)
      {
        if (A > mid_c and B > mid_c or A < mid_c and B < mid_c)
        {
          return A == B;
        }
        else
        {
          if (A > mid_c)
            A = A - 'a' + 'A'; 
          if (B > mid_c)/// convert all uppercase letters to a lowercase ones
            B = B - 'a' + 'A';
          /// this could be changed to B = B + up2lo;
          return A == B;
        }
      }
}

Dies könnte wahrscheinlich viel effizienter gestaltet werden, aber hier ist eine sperrige Version mit allen Teilen.

Nicht ganz so portabel, funktioniert aber gut mit allem, was sich auf meinem Computer befindet (keine Ahnung, ich mag Bilder, nicht Worte)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top