Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4960655
  • 博文数量: 1696
  • 博客积分: 10870
  • 博客等级: 上将
  • 技术积分: 18357
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-30 15:16
文章分类
文章存档

2017年(1)

2016年(1)

2015年(1)

2013年(1)

2012年(43)

2011年(17)

2010年(828)

2009年(568)

2008年(185)

2007年(51)

分类: C/C++

2008-11-05 06:35:22

C++给本地化字符串排序 
 
问题
有一序列,它含有非ASCII字符的字符串,如何根据本地环境来对它们进行排序?
解决方案
这个locale类通过重载一个操作符为在一个给定的locale内比较字符提供了内在的支持。当你调用任何带有算符作为比较时的标准函数时,你可以使用这个locale类的实例作为你的比较算符(请参考示例13-8)。
示例13-8  特定于locale的排序
#include
#include
#include
#include
#include
using namespace std;
bool localeLessThan (const string& s1, const string& s2) {
   const collate& col =
     use_facet >(locale()); // Use the global locale
   const char* pb1 = s1.data();
   const char* pb2 = s2.data();
   return (col.compare(pb1, pb1 + s1.size(),
                       pb2, pb2 + s2.size()) < 0);
}
int main() {
   // Create two strings, one with a German character
   string s1 = "di鋞";
   string s2 = "dich";
   vector v;
   v.push_back(s1);
   v.push_back(s2);
   // Sort without giving a locale, which will sort according to the
   // current global locale's rules.
   sort(v.begin(), v.end());
   for (vector::const_iterator p = v.begin();
        p != v.end(); ++p)
      cout << *p << endl;
   // Set the global locale to German, and then sort
   locale::global(locale("german"));
   sort(v.begin(), v.end(), localeLessThan);
   for (vector::const_iterator p = v.begin();
        p != v.end(); ++p)
      cout << *p << endl;
}
第一个排序遵循了ASCII排序的惯例,因此它的输出如下:
dich
di妕
第二个排序根据德文的语义使用了正确的顺序,因此它的输出如下:
di妕
dich
讨论
当你在不同的环境中工作时,排序变得非常复杂,并且标准类库解决了这个问题。facet collate提供了一个成员函数compare,它就像strcmp函数:当第一个字符串小于第二字符串时,它返回-1,相等时返回0,而当第一个字符串大于第二个字符串时,返回1。与strcmp函数不同的是,collate::compare使用了目标locale中的字符语义。
示例13-8中说明了函数localeLessThan,根据这个全局的locale,如果第一个参数小于第二个参数,它就返回真值。这个函数中最重要的部分是调用compare函数。
col.compare(pb1,             // Pointer to the first char
a
            pb1 + s1.size(), // Pointer to one past the last char
            pb2,
            pb2 + s2.size())
依赖于你的实现中执行的字符集,示例13-8可能返回我前面说明的结果,也可能与之不同。但是如果你需要保证这个字符串的比较与某个特定于locale的方式相同,你就应该调用collate::compare。当然,标准没有要求实现支持除了“C”之外的任何locale,因此你需要通过测试来验证你的实现是否支持你需要支持的locale。

 
阅读(1113) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~