string
string
是长度不定的字符串。为了使用string
类型,需要:
#include <string>
using std::string;
当然,有的编译器可能直接把上述内容直接包含到<iostream>
等,参见
can std::string be used without #include
定义和初始化string
下面是最常见的初始化string的方法:
string s1; // 默认初始化;s1是个空串
string s2(s1); // s2 是 s1 的拷贝
string s2 = s1; // 等价于 s2(s1)。
string s3("value"); // 字符串字面常量的拷贝
string s3 = "value"; // 等价于 s3("value")
string s4(n, 'c'); // 用n个字符'c'的拷贝初始化
初始化的直接或拷贝形式
当我们使用=
初始化变量时,是在要求编译器去拷贝初始化(copy initialize);当忽略=
时,就是直接初始化(direct initialization)。
当我们只有一个初始化器时,使用初始化的拷贝或直接初始化是无所谓的。当我们要从多个值初始化变量,比如上面的s4,我们必须使用直接初始化。
string s5 = "hiya"; // 拷贝初始化
string s6("hiya"); // 直接初始化
string s7(10, 'c'); // 直接初始化
注意string s8 = string(10, 'c')
这样的拷贝初始化,显式地创建了一个临时对象。
string的操作
下面是string对象的最常见的操作:
os << s // 写s到流os;返回os
is >> s // 从is读空白符分隔的字符串到s;返回is
getline(is, s) // 从is读取一行输入到s;返回is
s.empty()
s.size()
s[n] // 返回n位置字符的引用
s1 + s2
s1 = s2
s1 == s2
s1 != s2
< <= > >=
读取不确定数目的strings:
string word;
while(cin >> word)
cout << word << endl;
使用getline
读取整行:
while(getlien(cin, line))
cout << line << endl;
string::size_type类型
我们可能很自然的想:size
返回的是int
或者unsigned
。当实际上,它返回的是string::size_type
类型。
string
和很多库类型定义了很多伴随类型(companion type)。这使得它能够依赖机器的使用。size_type
就是一个伴随
类型。虽然我们不知道其具体类型,但我们知道它是一个无符号类型,足以容纳任何大小的字符串。
显然,写代码时敲出string::size_type
很麻烦,我们可以使用auto
或者decltype
。
strings和字面字符串的相加
要注意的是,使用+来连接它们时,至少一个得是string类型。
string s4 = s1 + ","; // ok
string s5 = "hello" + ","; // error
string s6 = "hello" + "," + s2; // error
因为历史原因,和为了和C语言兼容,字符串字面常量不是标准库里的strings。
处理字符
关于处理字符的函数,比如判断是不是字母,是不是大写等,都在cctype
头文件里。
函数 | 解释 |
---|---|
isalpha | 是不是大写 |
isdigit | 是不是数字 |
... | ... |
使用C++版本的C库。建议使用c开头的版本,而不是.h版本。
范围for
C++ 11引入了新的range for
语句。语法是:
for (declartion : expression)
statement
比如下面的遍历字符串的语句,
string str("hello world");
for (auto c : str)
cout << c << endl;
下面是统计字符串里面的标点符号数:
string s("hello world!!!");
decltype(s.size()) punct_cnt = 0;
for (auto c : s)
if (ispunct(c))
++punct_cnt;
在range for里面修改字符串
如果要在range for里面修改字符串,必须把循环变量定义成引用类型。
下面是把字符串里面的字符都变成大写的:
for (auto &c : s)
c = toupper(c);
如果不使用引用,对原串没有影响。
下标操作符
下标操作符[]接受的是一个string::size_type类型的参数。如果传递一个signed的值,会先变成unsinged。
需要手动检查下标的合法边界。