2015-02-07 6 views
6

मुझे सी ++ के लिए पता है कि मूल तुलनात्मक ऑपरेटरों कार्य को पूरा कर सकते हैं यदि दोनों शब्द या तो पूरी तरह से कम या पूरी तरह से ऊपरी मामले हैं। मेरे पास तारों की एक सरणी है और अक्षर निम्न से ऊपरी तक भिन्न हो सकते हैं। यहाँ तार की तरह का एक छोटा सा examle मैं के साथ काम किया जा सकता है:क्या सी स्ट्रिंग :: स्ट्रिंग :: स्ट्रिंग :: स्ट्रिंग :: स्ट्रिंग :: लोअरकेस हो सकता है जब दो तारों की तुलनात्मक रूप से दो तारों की तुलना करने के लिए स्ट्रिंग :: स्ट्रिंग में कोई अंतर्निहित फ़ंक्शन है?

"अबंडंट लाइफ़ सीएच"

"नया जीवन WMN MNSTRY"

"नया जीवन विधानसभा"

मुझे पता है जावा में फ़ंक्शन String.compareToIgnoreCase() मौजूद है। क्या इस समारोह के बराबर सी ++ है?

+0

नहीं कोई केस-संवेदी मानक पुस्तकालय में तुलना कार्य है। मानक सी पुस्तकालय में भी आप नहीं कर सकते हैं। –

+0

डारन मुझे डर था कि यह सच होना चाहिए। – WorthAShot

+0

क्या आपका टेक्स्ट ASCII तक सीमित है? – Deduplicator

उत्तर

6

मैं मानक पुस्तकालय में किसी भी केस-संवेदी कार्यों के बारे में पता नहीं है, लेकिन आप 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)); 
    }); 

एक समाधान जिसके खाते में स्थान लेता है, Case insensitive 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())); 
} 
+0

जो कभी-कभी लोकेल के आधार पर काम करता है। और यह सभी दिए गए उदाहरणों के लिए काम करता है। – Deduplicator

+0

@Deduplicator क्या आप इस मुद्दे को समझा सकते हैं? 'Std :: tolower' locale-aware नहीं है? – sbabbi

+0

@sbabbi: हाँ, यह है। लेकिन यह मदद नहीं करता है उदा। अपरकेसिंग 'ß'। कई अन्य उदाहरण हैं ... – Deduplicator

3

हाँ वहाँ सी ++ में तार की तुलना करने के एक मामले असंवेदनशील तरीका है।

template <class charT, 
      class traits = char_traits<charT>, 
      class Allocator = allocator<charT>> 
class basic_string; 

traits यहाँ पर नियंत्रण कैसे charT के एक दूसरे से संबंधित: महत्वपूर्ण यह है कि std::string एक टेम्पलेट है। सामान्य 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; 
    } 
}; 
इसी के साथ

:

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

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

assert(a == b); 
+0

1+ के रूप में पार करना बेहतर है, मुझे वास्तव में यह समाधान पसंद है, यह साफ़ और बहुत पठनीय और रखरखाव योग्य है। – deW1

+0

केवल 1-बाइट वर्णों के लिए काम करता है, यानी यह 1 char में फिट बैठता है, इसलिए यह यूटीएफ -8 के लिए कुछ भी काम नहीं करेगा। –

+0

@ बेनोइट 'charT'' basic_string' पर भी एक टेम्पलेट है, इसलिए आप आसानी से 'case_insensitive_traits' को चार प्रकार के रूप में टेम्पलेट करने के लिए बढ़ा सकते हैं। – Barry

1

सी में से कम (bool ++ आमतौर पर कम (प्रकार, प्रकार)) त्रि-मूल्य फ़ंक्शन तुलना (int cmp (प्रकार, प्रकार) के स्थानों में उपयोग किया जाता है)। बेशक उनमें से प्रत्येक को दूसरे के संदर्भ में छोटा रूप से परिभाषित किया जा सकता है।

यहाँ कुछ है कि आसानी से एसटीएल एल्गोरिदम में जोड़ा जा सकता है:

template<class String> 
struct ciless { 
    locale l_; 

    explicit ciless(locale l = locale()) : l_(l) {} 

    bool operator() (
     String const &a 
    , String const &b) const 
    { 
    auto fa = a.begin(); 
    auto fb = b.begin(); 

    while (fa != a.end() 
     && fb != b.end() 
     && (tolower(*fa, l_) == tolower(*fb, l_))) 
    { 
     ++fa; 
     ++fb; 
    } 

    return 
     (fa == a.end() && fb != b.end()) 
     || (
      fa != a.end() 
     && fb != b.end() 
     && tolower(*fa, l_) < tolower(*fb, l_)); 
    } 
}; 

और यहाँ) कुछ है कि कम() जावा शैली में बदल सकते हैं की तुलना (है:

template<class T, class Less = std::less<T>> 
struct compare 
{ 
    Less l_; 

    explicit compare(Less l = Less()) : l_(l) {} 

    int operator() (
     T const &a 
    , T const &b) const 
    { 
    if (l_(a, b)) 
     return -1; 

    if (l_(b, a)) 
     return 1; 

    return 0; 
    } 
}; 
0

कुछ भी नहीं मानक है, लेकिन यदि आप विंडोज के लिए विकास करना चाहते हैं या पॉज़िक्स इंटरफ़ेस तक पहुंच प्राप्त कर रहे हैं तो आप निम्न का उपयोग कर सकते हैं: https://msdn.microsoft.com/en-us/library/k59z8dwe.aspx

// didn't run it through a compiler 
// but it would look like something like this: 
{ 
    using namespace std; 
    string a = "HELLO"s; 
    string b = "HelLO"s; 
    bool bIsMatch = _stricmp(a.c_str(), b.c_str()) == 0; // bIsMatch = true 
} 
2

आप स्ट्रिंग एल्गोरिदम बूस्ट का उपयोग कर सकते हैं:

#include <string> 
#include <cassert> 

#include <boost/algorithm/string.hpp> 

int main() { 
    std::string s { "Test" }; 
    assert(boost::iequals(s, "TEST")); 
} 
संबंधित मुद्दे