CC++ & Algorithm

string类:魔法书包,装文字更轻松

中等13
语言版本:C++
概述:string类像一个可以自动变大的魔法书包,用来存放字符串,操作起来比字符数组方便很多。

string类——让文字处理像玩一样简单

小朋友,你有没有遇到过这样的烦恼:用字符数组存一句话,得先猜它最长有多长,还要时刻记得最后加个 '\0',不然就会出错?别担心,C++里有一个特别方便的工具——string 类。它就像一个魔法书包,你想装多少文字它就能装多少,书包会自动变大变小,而且自带很多好用的功能,比如连接两个字符串、数一数有几个字、甚至还能直接比较谁长谁短。今天我们就来好好认识一下这个“文字好帮手”。

怎么使用 string?

要使用魔法书包,得先告诉C++:“我要用 string 了”。所以在程序开头加上:

#include <string>

(有些编译器可能自动包含了,但自己写上更保险,就像出门带好钥匙一样!)

然后就可以像普通变量一样定义它。比如:

string myName = "小明";  // 定义一个字符串变量,存你的名字
string favoriteFood = "巧克力";  // 存你最喜欢的零食

拼接字符串——像搭积木一样简单

以前用字符数组拼接字符串,得用 strcat,还要小心长度不够。用 string 就简单了,直接用 + 号就能把两个字符串连起来,就像把两块积木拼在一起。

生活例子:你的姓和名分开存放,想得到全名,用 + 一拼就行。

#include <iostream>
#include <string>
using namespace std;
int main() {
    string firstName = "小明";  // 名字
    string lastName = "王";     // 姓
    string fullName = lastName + firstName;  // 拼接成 "王小明"
    cout << "全名:" << fullName << endl;
    cout << "名字的长度是:" << fullName.size() << "个字符" << endl;

    // 还可以像数组一样用下标访问某个字符
    cout << "第一个字是:" << fullName[0] << endl;   // 输出 '王'
    cout << "第二个字是:" << fullName[1] << endl;   // 输出 '小'
    return 0;
}

你看,+ 把两个字符串连到了一起,.size() 告诉我们字符串里有多少个字符(比如“王小明”是3个字符),[0] 还能取出第一个字。是不是比字符数组方便多了?

更多拼接小技巧:你还可以把多个字符串连在一起,比如:

string s1 = "Hello";
string s2 = " ";
string s3 = "World";
string result = s1 + s2 + s3;  // 结果是 "Hello World"

甚至可以直接在字符串后面加一段文字:

string greeting = "你好";
greeting = greeting + ",朋友!";  // 变成 "你好,朋友!"

输入带空格的字符串——用 getline 帮忙

平时我们用 cin >> 输入字符串时,只要碰到空格或回车就会停下来。比如你想输入一句话“我 爱 编程”,用 cin 只能读到“我”。怎么办?string 有个好伙伴叫 getline,它可以一次读一整行,包括空格。

string sentence;                   // 定义一个空字符串
cout << "请输入一句完整的话(可以有空格):";
getline(cin, sentence);            // 读入一整行,直到用户敲回车
cout << "你输入的是:" << sentence << endl;

小提示:如果你在 getline 之前用了 cin >>(比如先读一个整数),可能会遇到“换行残留”问题。解决办法是在 cin >> 后面加一句 cin.ignore(); 或者用 getline 前多读一次换行符。我们后面会讲到。

常见错误,避开这些坑

  1. 忘记 #include <string>
    有些编译器可能不报错,但为了安全,一定要加上。就像出门要带钱包一样重要。

  2. 混合使用 cin >>getline
    比如:

    int age;
    cin >> age;              // 读一个整数,敲回车后,换行符还留在输入缓冲区
    string name;
    getline(cin, name);      // 会直接读到那个换行符,导致 name 变成空字符串!
    

    解决方法:在 cin >> age; 后面加 cin.ignore(); 清除换行符。

  3. 用下标访问时越界
    string s = "hi"; 那么 s[0]s[1] 可以,但 s[2] 就不行了(会输出奇怪的东西或程序崩溃)。虽然 string 会自动变大,但下标访问不会自动扩容,要小心。

  4. 以为 == 不能比较字符串
    其实 string 是支持 ==!=<> 的比较的!比如 "abc" == "abc"true"abc" < "bcd" 也是对的(按字典顺序)。这和字符数组用 strcmp 不一样,更直观。

完整示例:帮老师统计班级名单

下面是一个完整的程序,用来输入三个同学的名字,拼接成一句话,然后输出总人数和每个名字的长度。

#include <iostream>
#include <string>   // 使用 string 必须包含这个头文件
using namespace std;
int main() {
    string name1, name2, name3;   // 三个同学的名字

    cout << "请输入第一位同学的名字(可以有空格):";
    getline(cin, name1);           // 读入一整行(包括空格)

    cout << "请输入第二位同学的名字:";
    getline(cin, name2);

    cout << "请输入第三位同学的名字:";
    getline(cin, name3);

    // 拼接成一句话
    string allNames = name1 + "、" + name2 + "、" + name3 + "。";
    cout << "名单:" << allNames << endl;
    cout << "总共有 " << allNames.size() << " 个字符(包括标点)。" << endl;

    // 输出每个名字的长度
    cout << name1 << " 的长度是 " << name1.size() << endl;
    cout << name2 << " 的长度是 " << name2.size() << endl;
    cout << name3 << " 的长度是 " << name3.size() << endl;

    // 用下标访问第一个名字的第一个字
    if (name1.size() > 0) {
        cout << "第一位同学名字的第一个字是:" << name1[0] << endl;
    }

    return 0;
}

运行效果:

请输入第一位同学的名字(可以有空格):张三丰
请输入第二位同学的名字:李小龙
请输入第三位同学的名字:王小花
名单:张三丰、李小龙、王小花。
总共有 13 个字符(包括标点)。
张三丰 的长度是 3
李小龙 的长度是 3
王小花 的长度是 3
第一位同学名字的第一个字是:张

还有哪些好玩的?

string 还有很多魔法功能,比如:

  • 查找find("关键词") 可以在字符串里找某个词的位置。
  • 替换replace(位置, 长度, "新内容") 可以替换掉一部分。
  • 子串substr(起始位置, 长度) 可以取出字符串中间的一段。
  • 插入与删除inserterase 可以灵活修改字符串。

这些功能就像魔法书包里的小工具,等你以后慢慢探索!如果你想进一步学习,可以看看“字符串的查找与替换”“用 string 做密码验证”等内容。

记住:以后写程序处理文字,优先考虑用 string,它比字符数组好用太多啦!

例题精讲

1单选题

以下关于C++ string类的说法中,错误的是?

Astring类可以直接用等号进行赋值操作
Bstring类可以通过下标运算符[]访问单个字符
Cstring类对象的大小可以通过size()或length()获取
Dstring类对象定义后,其容量是固定不变的
2判断题

C++ string类对象可以被当作字符数组使用,也可以通过下标修改其中的字符。

3填空题
下面程序的功能是从字符串s中查找子串"hello"第一次出现的位置,并输出该位置。请补全代码。
#include <iostream>
#include <string>
using namespace std;
int main() {
    string s = "hihelloworld";
    int pos = s.___("hello");
    cout << pos << endl;
    return 0;
}
4单选题

下列哪个表达式可以将两个string对象s1和s2连接起来?

As1 + s2
Bs1.append(s2)
Cs1 += s2
D以上都是
5填空题
下面程序将字符串s中的第一个字符删除,然后输出新字符串。请补全代码。
#include <iostream>
#include <string>
using namespace std;
int main() {
    string s = "hello";
    s.___(0, 1); // 删除从位置0开始的1个字符
    cout << s << endl;
    return 0;
}