《Hello C++》4.2 string 类

《Hello C++》4.2 string 类
0x3ff18a在前面学习数组时,我们已经知道了如何存放一组相同类型的数据。现在我们再往前走一步,认识 C++ 中非常常用的一种字符串类型:std::string[1]。
在前面的程序中,我们其实已经使用过 cin 和 cout 这样的标准库对象,只是当时还没有集中讨论“类、类型和对象”的关系。这一次,咱们会把 std::string 当作本节的主角,正式认识一种标准库类类型,并学习怎样创建和使用这种类型的对象。
std::string 专门用于表示和操作字符串。与 C 风格字符串相比,它能自行管理保存字符所需的存储空间,并提供赋值、拼接、查询长度等操作。使用者通常不需要亲自维护末尾的空字符 '\0',因此日常字符串处理会方便许多。
4.2.1 string 类简介
字符串就是一串字符的组合,比如名字、句子、路径、提示信息等,都是字符串。C++ 标准库提供了 std::string 类型来表示这类数据。
1 |
|
其中最关键的一条语句是 string name = "Hello";。它定义并初始化了一个名为 name 的变量,string 表示变量的类型,name 是变量名,"Hello" 是它的初始内容。由于 string 是类类型,因此 name 同时也是一个 string 对象。这里发生的是初始化,而不是先创建对象再进行赋值。
这里需要把几个容易混淆的词分开:
- 类:用于规定一类对象可以保存什么数据、提供什么操作;
- 类类型:由类所定义的类型;
std::string是标准库提供的一个类类型名称; - 对象:某个类型在程序中的具体实体;这里的
name是一个string对象; - 变量:由声明引入名称的对象或引用;这里的
name是一个有名称的对象,因此同时也是一个变量。
因此,不能说“string 是一个类的对象”。在这段代码里,string 表示类型,name 才是该类型的对象。对象和变量也不是互相排斥的称呼:从类型与对象的关系看,name 是对象;从代码通过名称使用它这一点看,name 是变量。
这是本书第一次把一个标准库类类型作为主要内容来学习,但并不是第一次使用对象:前面出现的 cin 和 cout 也是对象。
你现在先记住:std::string 表示一种类类型,name 是这种类型的一个对象,也是一个变量。第 7 章会进一步讲解类怎样定义类型,以及对象怎样根据类型创建出来。
4.2.2 字符串初始化
string 的初始化方式很灵活,常见写法有下面几种。
1 | string a; |
第一种是不带初值,表示先创建一个空字符串。第二种和第三种都很常见,第四种则是 C++11 之后更现代的写法。
如果你想创建一个空字符串,也可以直接这样写:
1 | string empty = ""; |
初始化后,你就可以对字符串进行赋值、拼接、附加和输出等操作了。
4.2.3 字符串赋值
string 的赋值非常直接,和普通变量很像。
1 | string name; |
这表示先声明一个字符串变量,再把 "Alice" 赋给它。你也可以把一个 string 赋给另一个 string。
1 | string a = "Hello"; |
这时,b 的内容就变成了 "Hello"。
4.2.4 字符串拼接和附加
字符串最常见的用途之一,就是把几个片段拼起来。
1 | string first_str = "Hello"; |
这里 + 表示拼接,最终 full_str 的内容就是 "Hello C++"。
如果你想在原有字符串后面继续加内容,可以使用 +=,也就是附加。
1 | string text = "Hello"; |
这时 text 的内容会变成 "Hello world"。+= 的好处是很直观,意思就是“在原来的基础上继续加”。
你还可以连续拼接多个字符串:
1 | string result = "Hello" + string(" ") + "C++"; |
4.2.5 string 类的其他操作
string 类除了能初始化、赋值和拼接之外,还有一些非常实用的操作。
例如,查看长度:
1 | string s = "Hello"; |
size() 和 length() 这两个成员函数通常都能返回字符串长度,很多时候可以互换使用。
你还可以访问某个位置上的字符:
1 | char ch = s[1]; |
这表示取出字符串中的第二个字符。和数组类似,字符串下标也是从 0 开始的。
如果你想判断字符串是否为空,也可以这样写:
1 | if (s.empty()) |
这些操作让 string 变得非常实用,因为它不像 C 风格字符串那样需要你自己去处理很多细节。
4.2.6 string 类 I/O
string 的输入和输出也很方便。
1 |
|
这里的 cin >> name 会读取一个单词,也就是说它会在遇到空格时停止。
如果你想读取包含空格的一整行文本,可以使用 getline():
1 | string line; |
getline() 会把一整行内容都读进来,包括空格,直到遇到换行符为止。这一点在读取姓名、句子、地址等内容时特别有用。
4.2.7 其他形式的字符串字面值
前面我们经常看到 "Hello" 这种写法,它叫做字符串字面值[2]。在 C++ 中,字符串字面值还有一些其他形式。
比如原始字符串字面值[3]:
1 | cout << R"(C:\Users\Hello\Desktop)" << endl; |
这种写法可以减少转义符号的烦恼。对于路径、正则表达式、带很多反斜杠的文本,它尤其方便。
还有宽字符串字面值[4]:
1 | wchar_t ws[] = L"Hello"; |
这类写法通常用于更宽字符集的处理。初学阶段你先知道它们存在就可以,后面如果真的遇到,再按需要深入学习。
4.2.8 小结
string 类让字符串处理变得比 C 风格字符串更自然,也更安全。你可以轻松地初始化、赋值、拼接、附加、读取和输出字符串,还可以用 size()、empty() 之类的成员函数来管理它。
更重要的是,这一小节是你第一次比较正式地接触“类”的概念。你现在先不用急着把类想得太复杂,只要记住:string 是标准库提供的一个类,而你使用的 string 变量,就是这个类创建出来的对象。后面我们会专门花一章,把“类是什么、对象是什么、它们为什么这么重要”讲清楚。







