C++使用类模板 basic_string 来存放字符串数据,并提供了一组成员函数来处理该字符串
basic_string 还具有一个明显的优势:自动内存管理功能
类 string 及 wstring 是 basic_string 特化的结果
typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;
basic_string 常见的构造函数及其使用方法
对于 wchar_t
类型的 basic_string,最好在字符串常量的前面加上前缀“L”
#include
#include
using namespace std;
int main()
{
basic_string<char> s1;
basic_string<char> s2 ("hello world");
basic_string<char> s3 ("hello world", 5);
basic_string<char> s4 ( s2, 6, 5);
cout << s1 << endl << s2 << endl << s3 << endl << s4 << endl;
// 加了L前缀的字符串
basic_string<wchar_t> ws (L"得友难失友易(A friend is easier lost than
found)");
wcout.imbue(locale("chs"));
wcout << "size is: " << sizeof(ws[7]) << endl << ws << endl;
}
c_str()
该函数返回一个指针,指向 basic_string 中存放的字符串数据
对于 string
类型,该函数返回char *
;
对于 wstring
类型,该函数返回wchar_t *
;
basic_string 的类模板存在一个专门存放字符串长度的成员变量,通过 length()直接获取字符串长度,可以相对于 strlen()方法获取长度节省很多时间
QString 能对 Unicode 字符串进行拼接、查找等操作
不建议使用 basic_string 中的 wstring 替换掉 QString,因为前者对于标点符号判断等其他操作支持较差,而后者封装完善便于拿来即用
利用 fromLocal8Bit()
,将该字符串转换为 Unicode 编码的字符
QString 的成员函数 data()
返回一个指针,指向 QChar 序列
QString 自带的字符编码转换功能展示:
// 定义 main 函数
int main()
{
// 定义一个 char* 类型的字符串 humor,包含了英文和中文字符
char * humor = "Your future depends on your dream. So go to sleep.\n"
"你的梦想决定你的未来,所以睡觉去吧。";
// 将 humor 转换为 QString 类型的字符串 qs,使用 fromLocal8Bit 方法将 humor 中的字符转换为本地编码
QString qs = QString::fromLocal8Bit(humor);
// 将 qs 转换为 QByteArray 类型的数据 data,使用 toUtf8 方法将 qs 中的字符转换为 UTF-8 编码
QByteArray data = qs.toUtf8();
// 打开文件 utf8.txt,以二进制模式写入数据
ofstream of("utf8.txt", ios::binary);
// 将 data 中的数据写入文件,使用 data.data() 获取数据指针,data.length() 获取数据长度
of.write(data.data(), data.length());
}
类 QByteArray
被用来存放长度可变的字节序列,其中的字节序列被存放在一个地址连续的内存块中
该类总会在字节序列的末尾添加一个额外的“\0”
字符
C++标准库提供了类 locale
以及 facet
,分别用来描述某个区域的区域文化以及文化刻面
所有流对象都会共享一个全局的 locale 对象
一般的,开发者不需要知道 facet 的原理,直接使用 locale 即可实现区域文焕转换设定
下方代码展示了使用 cout 输出区域文化为德国的文本
#include
#include
using namespace std;
int main( )
{
double x = 1234567.123456;
cout.imbue( locale( "German_germany" ) );①
cout << fixed << x << endl;
}
每个 facet 子类描述某个文化刻面。C++标准库定义了 12 个常用的 facet 子类,来刻画时间、货币等表达方式
facet 对象不能够单独存在,它们必须隶属于某个 locale 对象
通过调用函数模板 use_facet<>
可以获得一个 locale 对象中某个 facet 对象的引用
numpunct
是 facet 的一个子类,可以通过 use_facet
获取 facet 对象后对其实例化得到 numpunct 对象
#include
#include
// 定义 main 函数
int main()
{
// 创建一个 locale 对象 os_locale,使用默认本地化设置
locale os_locale("");
// 获取 os_locale 的数字标点符号,使用 use_facet 方法获取 numpunct 类型的 facet 对象
const numpunct<char>& np = use_facet<numpunct<char>>(os_locale);
// 输出数字标点符号的信息,包括小数点、千位分隔符、true/false 字符串等
std::cout << "number punctuation of " << os_locale.name() << std::endl;
std::cout << np.decimal_point() << " "
<< np.thousands_sep() << " "
<< np.falsename() << " " << np.truename() << std::endl;
// 获取数字分组信息,输出每个分组的长度
std::string group = np.grouping();
for (int i = 0; i < group.length(); i++) {
std::cout << i << "th grouping is: " << (int)group[i] << std::endl;
}
}
类模板 time_get
对一个表示日期和时间的字符序列进行解析,将其中的信息存放在结构体 tm 中
类模板 time_get 的基本使用方法
#include
#include
#include
// 定义 main 函数
int main()
{
// 创建一个 locale 对象 loc,使用默认本地化设置
locale loc;
// 获取 loc 的 time_get facet 对象 tg,用于解析时间信息
const time_get<char>& tg = use_facet<time_get<char>>(loc);
// 获取日期的顺序信息,使用 date_order() 方法获取日期的顺序,返回值为整数
int idx = tg.date_order();
// 输出本地化设置的名称和日期的顺序信息,message 数组用于将整数转换为字符串
char *message[] = {"no_order", "dmy", "mdy", "ymd", "ydm"};
std::cout << loc.name() << std::endl << "date order " << message[idx] << std::endl;
// 解析时间信息,使用 istringstream 类创建一个输入流 iss,包含了要解析的时间字符串 "10:26:00"
std::ios::iostate state = 0;
std::istringstream iss("10:26:00");
// 创建一个 istreambuf_iterator 对象 itbegin,指向 iss 的开头
std::istreambuf_iterator<char> itbegin(iss);
// 创建一个 istreambuf_iterator 对象 itend,指向 iss 的结尾
std::istreambuf_iterator<char> itend;
// 创建一个 tm 结构体对象 time,用于存储解析后的时间信息
std::tm time;
// 使用 time_get 的 get_time 方法解析时间信息,将结果存储在 time 中
tg.get_time(itbegin, itend, iss, state, &time);
// 输出解析后的时间信息
std::cout << time.tm_hour << ":" << time.tm_min << ":" << time.tm_sec << std::endl;
}
类模板 time_put
将存放在结构体 tm 中的日期和时间信息以某种特定的格式转化为一个字符序列
使用场景较少,不浪费过多笔墨介绍该类模板
类模板 codecvt
将某一种编码的字符串转换为另外一种编码的字符串
此为对应模板以及三个模板参数的含义
template
类模板 codecvt 的成员函数 in 的功能
#include
#include
// 定义 main 函数
int main()
{
// 定义 codecvt 类型的别名 cvt_type
typedef codecvt<wchar_t, char, mbstate_t> cvt_type;
// 创建一个 locale 对象 loc,使用默认本地化设置
locale loc;
// 获取 loc 的 codecvt facet 对象 cvt,用于字符编码转换
const cvt_type& cvt = use_facet<cvt_type>(loc);
// 定义字符数组,src 为待转换的字符串,dst 为存储转换结果的字符串
const int size = 20;
const char* p1, src[size] = "hello world!";
wchar_t* p2, dst[size];
// 定义 mbstate_t 对象 state,用于存储转换过程中的状态信息
mbstate_t state;
// 使用 cvt.in() 方法将 src 中的字符转换为 dst 中的宽字符
cvt_type::result result = cvt.in(state,
src, src + size, p1,
dst, dst + size, p2);
// 如果转换成功,输出转换结果
if (result == cvt_type::ok) {
std::wcout << dst << std::endl;
}
return 0;
}