《C++标准库》学习笔记 — STL — 国际化

本文详细介绍了C++中处理国际化问题的 Locale 概念,包括字符集、locale的定义和使用,以及facet的概念和重要性。通过示例展示了如何在C++中设置和使用locale进行数值、货币和时间格式化,以及字符分类和转换。文章探讨了facet的创建原则和分类,以及在C++11中对货币和时间的操作符支持。
摘要由CSDN通过智能技术生成

一、字符集

常用的字符集 utf-8unicode 标准的一种实现方案。utf-8 支持带 BOM 的版本。其为 byte order mark 的缩写,用以标识它所使用的是 big-endianlittle-endian

二、Locale 概念

解决国际化问题,通常是通过所谓的 locale(地域),它被用来封装国家以及文化之间的转换行为。C社区正是采用了这种做法。在国际化情境下,locale 就是一个 ”参数和函数的集合“,用以进行国家和文化之间的转换。根据 X/Open(Unix标准) 规约,环境变量 LANG 用来确定当前使用的 locale。根据这个 locale 于是定出不同的浮点数、日期、货币格式。
在这里插入图片描述
对于 windows 系统,可以借助 PowerShell 中的 Get-WinSystemLocale 命令来获取本地化信息。

1、locale 的定义

想要定义一个 locale,需要采用以下 string 格式:
language[_area[.code]][@modifier]
其中:

  • language 表示语言,例如英语或德语。它通常是包含两个小写字符如 en 或 de 的 string。
  • area 表示使用该语言的地域、国家或文化;它通常是“包含两个大写字符如US或DE”的string。
  • code 代表字符编码方案,其重要性在亚洲特别明显。因为在这里相同的字符集常常有不同的字符编码方案,如utf8、ISO-8859-1、eucJP。
  • modifier 允许某些平台指出额外修饰,例如@euro用于欧元符号,@phone用于对电话号码排序。
    请添加图片描述

2、使用 locale

对真正的国际化而言,仅仅翻译“文字所带的信息”往往不够。各种不同的数值、货币,日期等规格也都必须遵守。另外,用来操作字母的函数应该根据字符进行编码,以确保正确处理特定语言中所有身为字母的字符。

根据 POSIX 和 X/Open 标准,C程序可使用 setlocale() 设定一个locale。改变 locale 会对 issupper() 和 tosupper () 之类的字符分类操作函数及 printf() 之类的 I/O 函数产生影响。然而 C 解法毕竟有诸多限制。由于 locale 是全局属性,所以同时使用一个以上的 locale (例如按英文规则读取浮点数,按德文规则写出),虽非不可能,却很麻烦。此外 C 中的 locale 无法扩展,只能提供由实现选取的设施;如果某种国家规定或范式未被实现,那么我们就无法使用这种解决方案。

在C++标准库中,利用面向对象做法解决了上述所有问题。首先,与 locale 相关的细节被封装在类型为 locale 的对象中。仅仅如此,同一时间使用多个 locale 便成为可能。依赖于 locale 的各种操作都将通过具体对象得以展开。如:

#include <locale>
#include <iostream>
using namespace std;

int main()
{
   
	cin.imbue(locale::classic());
	cout.imbue(locale("deu_deu.1252"));
	cout << "input floating-point values" << endl;
	double value;
	while (cin >> value)
	{
   
		cout << value << endl;
	}
}

在这里插入图片描述
我们将英语中的浮点数转化为了德语的浮点数(, 和 . 是相反的)。

(1)locale 的默认构造

classic 函数用于获取典型的C风格的locale。我们可以使用 std::locale(“C”) 获得相同的 locale 对象。“C” 是个特殊名称,是所有C++实现唯一必须支持的名称。

我们可以选择使用 locale 的默认构造函数初始化一个 locale:

cin.imbue(locale());
cin.imbue(locale(""));

第一种方式将使用程序当前的全局 locale,第二种方式使用程序环境的本地locale。

(2)global 和 imbue

global 函数用于设置一个全局 locale 对象。需要注意的是其设置的全局对象所具备的属性只对使用默认构造函数所产生的 locale 对象生效,对于存在于既有流对象中的 locale 对象并不生效。

#include <locale>
#include <iostream>
using namespace std;

int main()
{
   
	double value = 2.3456;
	cout << "origin :" << value << endl;

	cout.imbue(locale());
	cout << 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值