2009-08-31 34 views
9

Tôi đang cố gắng so sánh std::string s theo cách phụ thuộc vào miền địa phương.đặt hàng phụ thuộc vào miền địa phương cho std :: string

Đối với chuỗi C-phong cách bình thường, tôi đã tìm thấy strcoll, mà thực hiện chính xác những gì tôi muốn, sau khi làm 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; 
} 

Tuy nhiên, tôi muốn có hành vi này cho std::string là tốt. Tôi chỉ có thể quá tải operator< để làm một cái gì đó giống như

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

nhưng sau đó tôi sẽ phải lo lắng về mã sử dụng std::lessstd::string::compare, vì vậy nó không cảm thấy đúng.

Có cách nào để làm cho loại đối chiếu này hoạt động cho các chuỗi theo cách liền mạch không?

Trả lời

7

toán tử() của std :: locale chỉ là những gì bạn đang tìm kiếm. Để có được ngôn ngữ toàn cầu hiện tại, chỉ cần sử dụng hàm tạo mặc định.

+0

Tiện dụng. Nó làm cho các bộ sưu tập tiêu chuẩn làm việc mà không cần nỗ lực. – CAdaker

7

Thư viện C++ cung cấp số collate facet để thực hiện đối chiếu địa phương cụ thể.

+0

toán tử() trên ngôn ngữ là cách dễ nhất tôi biết để truy cập vào nó. – AProgrammer

+1

Tôi hiểu - Tôi không biết điều đó. –

0

Trong C++, bạn cần sử dụng tiêu chuẩn đối chiếu khía cạnh. Check it out.

0

Sau một chút tìm kiếm, tôi nhận ra rằng một cách để thực hiện điều đó có thể là quá tải mẫu std::basic_string để tạo một chuỗi chuỗi được bản địa hóa mới.

Có lẽ là một lỗi gazillion trong này, nhưng như một bằng chứng của khái niệm:

#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, nó dường như không có tác dụng nếu bạn căn cứ trên char thay vì wchar_t và tôi không có ý tưởng tại sao ...

+0

Lý do char không hoạt động là nó không sử dụng unicode (như trong ".UTF-8". Có thể bạn đang sử dụng ISO/IEC 8859-1. –

+0

'& a + 1' nghĩa là gì? – 0x499602D2

Các vấn đề liên quan