其他章节:C++ Primer 学习心得
标准库类型string
表示可变长的字符序列,使用string
类型必须首先头文件,string
定义在命名空间std
中
#include <string>
using std::string
定义和初始化string
对象
初始化类的对象是由类本身决定的,一个类可以定义很多种初始化对象的方式。
string s1 // 默认初始化,s1是一个空串
string s2(sl) // s2是s1的副本
string s2 = s1 // 等价于s2(s1),s2是s1的副本
string s3("value") // s3 是字面值"value"的副本,除了字面值最后的那个空字符外
string s3 = "value" // 等价于s3("value"),s3是字面值"value"的副本
string s4(n, 'c') // 把s4初始化为由连续n个字符c组成的字符串
直接初始化和拷贝初始化
- 使用等号(
=
)初始化一个变量,执行拷贝初始化,把等号右侧的初始值拷贝到新创建的对象中去。 - 不使用等号(
=
),执行直接初始化。
初始值只有一个时,使用直接初始化或拷贝初始化都行;s4
样式的初始化用到的值有多个,一般只能使用直接初始化。
string s5 = "hiya"; // 拷贝
string s6("hiya"); // 直接
string s7(10, 'c'); // 直接
多个值进行初始化的情况,也可以采用拷贝初始化,需要创建一个临时对象用于拷贝:
string s8 = string(10, 'c'); // 拷贝
string
对象上的操作
os << s // 将s写到输出流os当中,返回os
is >> s // 从is中读取字符串赋给s,字符串以空白分隔,返回is
getline(is,s) // 从is中读取一行赋给s,返回is
s.empty() // s为空返回true,否则返回false
s.size() // 返回s中字符的个数
s[n] // 返回s中第n个字符的引用,位置n从0计起
s1 + s2 // 返回s1和s2连接后的结果
s1 = s2 // 用s2的副本代替s1中原来的字符
s1 == s2
s1 != s2 // 如果s1和s2中所含的字符完全一样,则它们相等:string对象的相等性判断对字母的大小写敏感
<, <=, >, >= // 利用字符在字典中的顺序进行比较,且对字母的大小写敏感
读写string
对象
cin >> s;
:执行读取操作时,string
对象自动忽略开头的空白(空格符、换行符、制表符等),从第一个真正的字符读起,直到遇见下一处空白。
string
对象的输入输出操作返回运算符左侧的运算对象作为结果,多个输入或输出可以连写在一起。
读取未知数量的string
对象
while (cin >> word){}
条件负责检测流的情况,流有效执行while
语句内部的操作;遇到文件结束标记或非法输入,循环结束。
使用getline
读取一整行
getline
:保留输入时的空白符,参数是输入流和一个string
对象,从输入流中读入内容,直到遇到换行符为止(换行符也读入),将所读内容存入string
对象(不保存换行符)。
getline
一遇到换行符就结束读取并返回结果。getline
返回流参数,可以使用getline
的结果作为while
条件。
string
的empty
和size
操作
empty
:string
的成员函数,返回string
对象是否为空的一个对应的bool
值。
size
:返回string
对象的长度(字符的个数)。
string::size_type
类型
size
函数返回值的类型,使用时通过作用域操作符表明是在string
中定义的。- 无符号整数类型,足够放下任何
string
对象的大小。表达式中避免混用带符号数和无符号数,有size
函数就不要再使用int
。
比较string
对象
string
对象相等意味着他们的长度相同且包含的字符也完全相同。
运算符==,!=,<,<=,>,>=
依照在大小写敏感的字典顺序。
- 如果两个
string
对象的长度不同,而且较短string
对象的每个字符都与较长string
对象对应位置上的字符相同,就说较短string
对象小于较长string
对象。 - 如果两个
string
对象在某些对应的位置上不一致,则string
对象比较的结果其实是string
对象中第一对相异字符比较的结果。
为string
对象赋值
对于string
,允许把一个对象的值赋给另外一个对象:
string stl(10,'c'),st2; // st1的内容是cccccccccc;st2是一个空字符串
stl = st2; // 赋值:用st2的副本替换st1的内容,此时st1和st2都是空字符串
两个string
对象相加
+
:得到新的string
对象,前半部分是+
左侧string
对象所含字符,后半部分是+
右侧string
对象所含字符。
+=
:复合赋值运算符,右侧string
对象追加到左侧string
对象的后面。
string sl = "hello, ", s2 = "world\n";
string s3 = sl + s2; //s3的内容是hello,world\n
s1 += s2; //等价于s1 = s1 + s2
字面值和string
对象相加
标准库允许将字符和字符串的字面值转换为string
对象,需要string
对象的地方可以使用这两种字面值来替代。
当把string
对象和字符及字符串字面值混在一条语句中使用时,必须确保每个加法运算符+
的两侧的运算对象至少一个是string
。
- C++中字符串字面值并不是标准库类型
string
的对象。
处理string
对象中的字符
cctype
头文件中定义了一组标准库函数处理字符。
alnum(c) // 当c是字母或数字时为真
isalpha(c) // 当c是字母时为真
iscntrl(c) // 当c是控制字符时为真
isdigit(c) // 当c是数字时为真
isgraph(c) // 当c不是空格但可打印时为真
islower(c) // 当c是小写字母时为真
isprint(c) // 当c是可打印字符时为真(即c是空格或c具有可视形式)
ispunct(c) // 当c是标点符号时为真(即c不是控制字符、数字、字母、可打印空白中的一种)
isspace(c) // 当c是空白时为真(即c是空格、横向制表符、纵向制表符、回车符、换行符、进纸符中的一种)
isupper(c) // 当c是大写字母时为真
isxdigit(c) // 当c是十六进制数字时为真
tolower(c) // 如果c是大写字母,输出对应的小写字母;否则原样输出c
toupper(c) // 如果c是小写字母,输出对应的大写字母;否则原样输出c
使用C++版本的C标准库头文件
- C语言的头文件形如
name.h
,C++将这些文件命名为cname
。 - 在名为
cname
的头文件中定义的名字从属于命名空间std
。
使用基于范围的for
语句处理每个字符
范围for
语句:遍历给定序列中的每个元素并对序列中的每个值执行某种操作。
for (declaration: expression)statement
expression
部分是一个对象,用于表示一个序列declaration
部分负责定义一个变量,该变量将被用于访问序列中的基础元素。每次迭代,declaration
部分的变量会被初始化为expression
部分的下一个元素值。
string str("Some string");
for (auto c: str) // 对于str中的每个字符
- 使用auto关键字让编译器来决定变量
c
的类型,每次迭代,str
的下一个字符拷贝给c
。
使用范围for
语句改变字符串中的字符
改变string
对象中的字符的值,必须把循环变量定义为引用类型。
string str("Some string");
for (auto &c: str) // 对于str中的每个字符
处理一部分字符
访问string
对象中的单个字符,使用下标,使用迭代器。
下标运算符([]
)接受的输入参数是string::size_type
类型的值,表示要访问的字符的位置;返回值是该位置上字符的引用。
string
对象的下标从0
记起,s[s.size() - 1]
是最后一个字符。string
对对象的下标必须大于等于0而小于s.size()
。- 下标的值称作“下标”或“索引”,任何表达式只要它的值是一个整形就能作为索引。如果某个索引是带符号类型的值将自动转换为无符号类型
string::size_type
。 - 访问字符之前,首先检查字符串是否为空。
使用下标执行迭代
for (decltype(s.size()) index = 0; index != s.size() && !isspace(s[index]); ++index)
使用下标执行随机访问
通过某个下标值,直接获取对应位置的字符,并不是每次都需要从前往后依次访问。