在第一个单元里,我们学习了 C++ 的生命周期和编程范式。在第二个单元里,我们学习了自动类型推导、智能指针、lambda 表达式等特性。今天,我们又要开始进入一个新的单元了,这就是 C++ 标准库。
以前,“C++”这个词还只是指编程语言,但是现在,“C++”早已变成了一个更大的概念——不单是词汇、语法,还必须要加上完备工整的标准库。只有语言、标准库“双剑合璧”,才能算是真正的 C++。反过来说,如果只单纯用语言,拒绝标准库,那就成了“天残地缺”。
看一下官方发布的标准文档吧(C++14),全文有 1300 多页,而语言特性只有 400 出头,不足三分之一,其余的篇幅全是在讲标准库,可见它的份量有多重。
而且,按照标准委员会的意思,今后 C++ 也会更侧重于扩充库而不是扩充语言,所以将来标准库的地位还会不断上升。
C++ 标准库非常庞大,里面有各式各样的精巧工具,可谓是“琳琅满目”。但是,正是因为它的庞大,很多人在学习标准库时会感觉无从下手,找不到学习的“突破口”。
今天我就先来讲和空气、水一样,最常用,也是最容易被忽视的字符串,看看在 C++ 里该怎么处理文本数据。
认识字符串
对于 C++ 里的字符串类 string,你可能最熟悉不过了,几乎是天天用。但你知道吗?string 其实并不是一个“真正的类型”,而是模板类 basic_string 的特化形式,是一个 typedef:
using string = std::basic_string<char>; // string其实是一个类型别名
这个特化是什么意思呢?
所谓的字符串,就是字符的序列。字符是人类语言、文字的计算机表示,而人类语言、文字又有很多种,相应的编码方式也有很多种。所以,C++ 就为字符串设计出了模板类 basic_string,再用模板来搭配不同的字符类型,就能够更有“弹性”地处理各种文字了。
说到字符和编码,就不能不提到 Unicode,它的目标是用一种编码方式统一处理人类语言文字,使用 32 位(4 个字节)来保证能够容纳过去或者将来所有的文字。
但这就与 C++ 产生了矛盾。因为 C++ 的字符串源自 C,而 C 里的字符都是单字节的 char 类型,无法支持 Unicode。
为了解决这个问题,C++ 就又新增了几种字符类型。C++98 定义了 wchar_t,到了 C++11,为了适配 UTF-16、UTF-32,又多了 char16_t、char32_t。于是,basic_string 在模板参数里换上这些字符类型之后,就可以适应不同的编码方式了。
using wstring = std::basic_string<wchar_t>;
using u16string = std::basic_string<char16_t>;
using u32string = std::basic_string<char32_t>;
不过在我看来,虽然 C++ 做了这些努力,但其实收效并不大。因为字符编码和国际化的问题实在是太复杂了,仅有这几个基本的字符串类型根本不够,而 C++ 一直没有提供处理编码的配套工具,我们只能“自己造轮子”,用不好反而会把编码搞得一团糟。
这就导致 wstring 等新字符串基本上没人用,大多数程序员为了不“自找麻烦”,还是选择最基本的 string。万幸的是 Unicode 还有一个 UTF-8 编码方式,与单字节的 char 完全兼容,用 string 也足以适应大多数的应用场合。

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



