首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

13.5 给本地化字符串排序

问题

有一序列,它含有非ASCII字符的字符串,如何根据本地环境来对它们进行排序?

解决方案

这个locale类通过重载一个操作符为在一个给定的locale内比较字符提供了内在的支持。当你调用任何带有算符作为比较时的标准函数时,你可以使用这个locale类的实例作为你的比较算符(请参考示例13-8)。

示例13-8  特定于locale的排序

#include <iostream>

#include <locale>

#include <string>

#include <vector>

#include <algorithm>

using namespace std;

bool localeLessThan (const string& s1, const string& s2) {

   const collate<char>& col =

     use_facet<collate<char> >(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<string> 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<string>::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<string>::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

            pb1 + s1.size(), // Pointer to one past the last char

            pb2,

            pb2 + s2.size())

依赖于你的实现中执行的字符集,示例13-8可能返回我前面说明的结果,也可能与之不同。但是如果你需要保证这个字符串的比较与某个特定于locale的方式相同,你就应该调用collate::compare。当然,标准没有要求实现支持除了“C”之外的任何locale,因此你需要通过测试来验证你的实现是否支持你需要支持的locale。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论