2009-08-31 36 views
9

के लिए लोकेल-निर्भर ऑर्डरिंग मैं लोकेल-निर्भर तरीके से std::string एस की तुलना करने की कोशिश कर रहा हूं।std :: string

साधारण सी शैली तार के लिए, मैं strcoll पाया है, जो करता है मैं वास्तव में क्या चाहते हैं, कर std::setlocale

#include <iostream> 
#include <locale> 
#include <cstring> 

bool cmp(const char* a, const char* b) 
{ 
    return strcoll(a, b) < 0; 
} 

int main() 
{ 
    const char* s1 = "z", *s2 = "å", *s3 = "ä", *s4 = "ö"; 

    std::cout << (cmp(s1,s2) && cmp(s2,s3) && cmp(s3,s4)) << "\n"; //Outputs 0 
    std::setlocale(LC_ALL, "sv_SE.UTF-8"); 
    std::cout << (cmp(s1,s2) && cmp(s2,s3) && cmp(s3,s4)) << "\n"; //Outputs 1, like it should 

    return 0; 
} 

हालांकि बाद, मैं भी std::string के लिए इस व्यवहार करना चाहते हैं। मैं सिर्फ operator< ओवरलोड सकता है की तरह

bool operator<(const std::string& a, const std::string& b) 
{ 
    return strcoll(a.c_str(), b.c_str()); 
} 

कुछ करने के लिए लेकिन फिर मैं std::less और std::string::compare का उपयोग कर कोड के बारे में चिंता करने की ज़रूरत होगी, तो यह सही नहीं लगता है।

क्या इस तरह के संयोजन को तारों के लिए एक सहज तरीके से काम करने का कोई तरीका है?

उत्तर

7

ऑपरेटर() std :: locale का सिर्फ वही है जो आप खोज रहे हैं। वर्तमान वैश्विक लोकेल प्राप्त करने के लिए, बस डिफ़ॉल्ट कन्स्ट्रक्टर का उपयोग करें।

+0

यह आसान है। यह मानक संग्रह बिना प्रयास किए काम करता है। लोकेल पर – CAdaker

7

सी ++ लाइब्रेरी लोकेल-विशिष्ट संयोजन करने के लिए collate facet प्रदान करती है।

+0

ऑपरेटर() इसे एक्सेस करने का सबसे आसान तरीका है। – AProgrammer

+1

मुझे लगता है - मुझे यह नहीं पता था। –

0

सी ++ में आपको मानक कोलेट पहलू का उपयोग करने की आवश्यकता है। Check it out

0

कुछ खोजने के बाद मुझे एहसास हुआ कि ऐसा करने का एक तरीका std::basic_string टेम्पलेट को एक नई, स्थानीयकृत स्ट्रिंग क्लास बनाने के लिए ओवरलोड करना हो सकता है।

शायद इस में एक gazillion कीड़े नहीं है, लेकिन अवधारणा के प्रमाण के रूप:

#include <iostream> 
#include <locale> 
#include <string> 

struct localed_traits: public std::char_traits<wchar_t> 
{ 
    static bool lt(wchar_t a, wchar_t b) 
    { 
     const std::collate<wchar_t>& coll = 
      std::use_facet< std::collate<wchar_t> >(std::locale()); 
     return coll.compare(&a, &a+1, &b, &b+1) < 0; 
    } 

    static int compare(const wchar_t* a, const wchar_t* b, size_t n) 
    { 
     const std::collate<wchar_t>& coll = 
      std::use_facet< std::collate<wchar_t> >(std::locale()); 
     return coll.compare(a, a+n, b, b+n); 
    } 
}; 

typedef std::basic_string<wchar_t, localed_traits> localed_string; 

int main() 
{ 
    localed_string s1 = L"z", s2 = L"å", s3 = L"ä", s4 = L"ö"; 

    std::cout << (s1 < s2 && s2 < s3 && s3 < s4) << "\n"; //Outputs 0 
    std::locale::global(std::locale("sv_SE.UTF-8")); 
    std::cout << (s1 < s2 && s2 < s3 && s3 < s4) << "\n"; //Outputs 1 

    return 0; 
} 

Howerver, यह काम करने के लिए यदि आप wchar_t के बजाय char को उसका आधार नहीं लगता है और मुझे पता नहीं है क्यों ...

+0

कारण चार काम नहीं करता है यह है कि यह यूनिकोड का उपयोग नहीं कर रहा है (जैसा कि ".UTF-8" में है। आप शायद आईएसओ/आईईसी 885 9 -1 का उपयोग कर रहे हैं। –

+0

'और ए + 1' क्या करना चाहिए? – 0x499602D2

संबंधित मुद्दे