您的位置:首页 > 编程语言 > C语言/C++

C++之国际化(2) --- locale

2014-03-03 13:30 453 查看
转载自:http://hi.baidu.com/nicker2010/item/8cc13bce77f11b3899b498eb

解决国际化问题,通常是通过locale环境,它被用来封装国家(地域)和文化之间的转换行为。

一个locale就是一个参数和函数的集合。根据X/Open公约,环境变量LANG用来确定当时的locale

不同的浮点数、日期、货币格式等则根据这个locale确定。

确定一个locale,需要采用以下字符串格式:

language[_area[.code]]

language表示语言,例如英语或者德语

_area表示该语言所处的地域、国家或者文化。用它可以在相同语言的不同国家之间实行转换

code定义字符编码方案,其重要性主要体现在亚洲,因为在那相同的字符集有不同的编码方案,如汉字的BIG5和GB

下面列出了典型的语言名称:

c Default: ANSI-C conventions (English, 7 bit)

de_DE German in Germany

de_DE. 88591 German in Germany with ISO Latin-1 encoding

de_AT German in Austria

de_CH German in Switzerland

en_US English in the United States

en_GB English in Great Britain

en_AU English in Australia

en_CA English in Canada

fr_FR French in France

fr_CH French in Switzerland

fr_CA French in Canada

ja_JP.jis Japanese in Japan with Japanese Industrial Standard (JIT) encoding

ja_JP.sjis Japanese in Japan with Shift JIS encoding

ja_JP.ujis Japanese in Japan with UNIXized JIS encoding

ja_JP.EUC Japanese in Japan with Extended UNIX Code encoding

ko_KR Korean in Korea

zh_CN Chinese in China

zh_TW Chinese in Taiwan

lt_LN.bit7 ISO Latin, 7 bit

lt_LN.bit8 ISO Latin, 8 bit

POSIX POSIX conventions (English, 7 bit)


但它们尚未标准化。

对程序而言,这些名称是否标准化无关紧要,

因为locale的信息是由使用者根据以某种形式提供的。

普遍的做法是:程序只需读取环境变量或者类似的数据库,判断可用的locales,

然后便可以将“选择正确locale名称"的任务交给使用者。

C程序可以使用函数setlocale()来设定一个locale。

改变locale会对isupper()和toupper()之类的字符函数以及printf()之类的I/O函数产生影响

但C的解决方案有很多的限制。

C++的标准中,locale则被泛化,设计得更有弹性

locale使用示例:

cin.imbue(locale::classic()); ///使用经典的C的locale从标准流中读取数据

cout.imbue(local("de_DE")); ///imbue函数用来安装locale,///德国的小数点为逗号(',')

double value;

while(cin>>value)

cout<<value<<endl;


其中cin.imbue(locale::classic());相当于cin.imbue(local("C"));

一般来说,除非需要读取某个固定格式来读取数据,否则程序不会预先定义一个特别的locale

而是会利用环境变量LANG来确定相应的locale

另外一种可能是读取一个locale名称然后利用之

示例代码:

locale langLocale(""); ///从环境变量LANG中读取缺省的locale对象

cout.imbue(langLocale);

bool isChina;

///locale.name()获取locale名称

if(langLocale.name() == "zh_CN" || langLocale.name() == "zh_TW")

isChina = true;

else

isChina = false;

if(isChina)

cout<<"输入locale名称:"<<endl;

else

cout<<"Input the name of locale:";

string locString;

cin>>locString;

if(!cin)

{

if(isChina)

cerr<<"读取数据时候发生错误!";

else

cerr<<"Error While reading";

return;

}

local cinLocale(locString.c_str());


cin.imbue(cinLocale);

string value;

while(cin>>value)

cout<<value<<endl;


locale类的静态函数global()可以用来安装一个全局的locale对象

这个对象可以用来作为某函数的locale对象参数的缺省参数

如果global()设定的locale对象是有名称的,则相当于C的locale调用了std::setlocale(LC_ALL,"")

不过,设定全局的locale对象,并不会替换已经存储于对象内部的locale。

它只能改变由缺省构造函数所产生的locale对象

例如下面的就是stream安装缺省的locale对象

cin.imbue(locale());

cout.imbue(locale());

cerr.imbue(locale());

下面是CodeBlocks中locale声明:

class locale

{

public:

typedef int category;

class facet;

class id;

class _Impl;

friend class facet;

friend class _Impl;

/**has_facet和use_facet是两个重要的友元函数

has_facet确定locale中是否有类型为_Facet的facet

use_facet返回locale中使用的类型为_Facet的facet对象的引用

*/

template<typename _Facet>

friend bool has_facet(const locale&) throw();

template<typename _Facet>

friend const _Facet& use_facet(const locale&);

template<typename _Cache> friend struct __use_cache;

/**locale中使用的facet*/

static const category none = 0;

static const category ctype = 1L << 0;

static const category numeric = 1L << 1;

static const category collate = 1L << 2;

static const category time = 1L << 3;

static const category monetary = 1L << 4;

static const category messages = 1L << 5;

static const category all = (ctype | numeric | collate |

time | monetary | messages);

/**不同类型的构造函数以及析构*/

locale() throw();

locale(const locale& __other) throw();

explicit locale(const char* __s); ///locale名为__s

//产生__base的一个副本,类型__cat中所有的facet将被__add的facet替换

locale(const locale& __base, const locale& __add, category __cat);

///相当于locale(__base, locale(__s),__cat);

locale(const locale& __base, const char* __s, category __cat);

///产生__other的一个副本,并安装__f所指的facet

template<typename _Facet> locale(const locale& __other, _Facet* __f);

~locale() throw();

const locale& operator=(const locale& __other) throw();

///产生this的一个副本,并将__other中型别为_Facet的facet装入

template<typename _Facet>locale combine(const locale& __other) const;

string name() const; ///locale的名称字符串

/**比较函数*/

bool operator==(const locale& __other) const throw ();

inline bool operator!=(const locale& __other) const throw ()

{ return !(this->operator==(__other)); }

///operator()使得我们可以运用locale对象作为字符串比较工具,运用collate facet,(STL仿函数的行为)

////使用示例:vetor<string> vec; std::sort(vec.begin(),vec.end(),locale("zh_CN"));

template<typename _Char, typename _Traits, typename _Alloc>

bool operator()(const basic_string<_Char, _Traits, _Alloc>& __s1,

const basic_string<_Char, _Traits, _Alloc>& __s2) const;

/**两个重要的成员函数global, classic

global将参数安装为全局的locale,并返回上一个全局locale

classic()返回locale("C")

*/

static locale global(const locale&);

static const locale& classic();

......

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: