一、从“char 字符数组时代”,进“string 新时代”。
🏰《string 王国奇遇记》—— C++ 中的 string 类型
1、故事开场:老房子 vs 智能城堡 🏚️🏰
在 C++ 世界里:
🧓char 字符数组
👉 像一排老房子房间要提前算好
忘记
'\0'就出事搬家(复制)很危险
🤖string
👉 像一座智能城堡房间不够会自己变大
自动管理结尾
很少踩坑
👑 国王说:
“小朋友,学会 string,你就能轻松写程序啦!”
2、string 是什么?🧠(第一认识)
📖 故事理解
string是一个会照顾自己的字符小队队长:
会记住自己有多长
会自动加“结束标志”
会自己整理房间
✨ 定义一个 string
#include <string> using namespace std; string name = "Tom";📌不需要'\0'!
📌不需要算长度!
3、string vs char 数组(简单对比)⚖️
| 项目 | char 数组 | string |
|---|---|---|
| 是否自动加结尾 | ❌ | ✅ |
| 会不会越界 | 容易 | 很少 |
| 能直接比较 | ❌ | ✅ |
| 能直接输入整行 | 麻烦 | 简单 |
| 适合小学生 | 😵 | 😄 |
👉直观结论:
“string 是 char 数组的PLUS升级版!”
4、string 的输入与输出 📥📤(超重要)
1️⃣ 输出(超级简单)
string s = "Hello"; cout << s;2️⃣ 输入一个单词
string s; cin >> s;📌 遇到空格会停(和 char 数组一样)
3️⃣ 输入一整句话 ⭐⭐⭐
string s; getline(cin, s);🧠 讲给学生的话:
“getline 是耐心的书记官,
一直写到你按回车。”
5、string 的长度 📏
📖 故事
string 自己会数人数,不用你操心!
string s = "Hello"; cout << s.length(); // 5或:
cout << s.size(); // 一样📌不数'\0',而且你也不用管它
6、访问 string 里的字符 🔍
string s = "Cat"; cout << s[0]; // C cout << s[1]; // a📌 和数组一样用下标
📌 但安全得多
7、string 的拼接魔法 🧩✨
📖 故事
string 会自动拉长城堡,
不用担心房子不够!
string a = "Hello "; string b = "Tom"; string c = a + b; cout << c; // Hello Tom还可以:
a += b;👉char 数组要用strcat,string 用+就行
8、string 的比较 ⚖️(超级友好)
📖 故事
string 自己知道怎么比大小!
string a = "cat"; string b = "cat"; if (a == b) { cout << "一样!"; }📌 不需要strcmp
📌 不需要<cstring>
9、string 的常用“魔法技能” 🪄(重点)
1️⃣ 判断是不是空的 🚪
if (s.empty()) { cout << "空字符串"; }小故事
string 王国里,有个小门卫检查城堡里有没有住人。
#include <iostream> #include <string> using namespace std; int main() { string s; cout << "请输入字符串:"; getline(cin, s); if (s.empty()) { cout << "城堡空空如也!" << endl; } else { cout << "城堡里有人:" << s << endl; } return 0; }示例输入输出
输入:
<回车>输出:
城堡空空如也!输入:
Tom输出:
城堡里有人:Tom2️⃣ 清空字符串 🧹
s.clear();小故事
string 王国的小朋友打扫城堡,把城堡里的字母全清理干净。
#include <iostream> #include <string> using namespace std; int main() { string s = "Hello World"; cout << "原来的字符串:" << s << endl; s.clear(); // 清空 cout << "清空后的字符串:" << s << endl; cout << "长度:" << s.length() << endl; return 0; }输出:
原来的字符串:Hello World 清空后的字符串: 长度:03️⃣ 查找字符或单词 🔍
string s = "I love C++"; s.find("love"); // 找到位置📌 找不到会返回:string::npos
小故事
string 王国有个侦探,要找某个字母或单词的位置。
#include <iostream> #include <string> using namespace std; int main() { string s = "I love C++"; string word = "love"; size_t pos = s.find(word); if (pos != string::npos) { cout << "'" << word << "' 在位置 " << pos << endl; } else { cout << "没找到 " << word << endl; } return 0; }输出:
'love' 在位置 2📌 注意:找不到会返回string::npos
4️⃣ 截取一部分子串 ✂️(做题很方便)
string s = "abcdef"; cout << s.substr(2, 3); // cde📌 从第 2 位开始,取 3 个
小故事
string 王国的剪刀手想剪下一段字母做成徽章。
#include <iostream> #include <string> using namespace std; int main() { string s = "abcdef"; string sub = s.substr(2, 3); // 从下标 2 开始,取 3 个字符 cout << "原字符串:" << s << endl; cout << "截取的子串:" << sub << endl; return 0; }输出:
原字符串:abcdef 截取的子串:cde5️⃣ 插入字符 🧱
string s = "Hello"; s.insert(5, "!");小故事
string 王国想在城堡中间插入一块砖,让城堡更漂亮。
#include <iostream> #include <string> using namespace std; int main() { string s = "Hello"; s.insert(5, "!"); // 在下标 5 插入 "!" cout << s << endl; return 0; }输出:
Hello!📌 下标从 0 开始计数
6️⃣ 删除字符 🗑️
s.erase(1, 2); // 删除 2 个字符小故事
string 王国里的清洁工把城堡中的某些字母删除。
#include <iostream> #include <string> using namespace std; int main() { string s = "Hello"; s.erase(1, 2); // 从下标 1 开始,删除 2 个字符 cout << s << endl; return 0; }输出:
Hlo📌 删除了'e'和'l',剩下'H'和'l'、'o'
10、string 和 char 数组如何互相变身 🔄(认识即可)
string → char 数组
string s = "Hello"; const char* p = s.c_str();
📌 小学生阶段了解就好
11、什么时候用 char 数组?什么时候用 string?🧭
👶 给学生的结论
🟢写作业 / 比赛 / 日常程序
👉 用string🧓学习底层 / 理解 C 语言 / 老代码
👉 才用 char 数组
12、送给学生的 string 口诀 🎵
string 是智能队长
不用尾巴不用忙
能拼能比还能剪
写起程序真方便!
13、课堂演示小程序
#include <iostream> #include <string> using namespace std; int main() { string name; cout << "请输入你的名字:"; getline(cin, name); cout << "你好," << name << endl; cout << "名字长度:" << name.length() << endl; if (name == "admin") { cout << "欢迎管理员!"; } }二、🕳️《string 王国 · 常见坑点》
🕳️ 坑 1:cin后直接getline(回车怪兽)👾
📖 故事
小朋友先用cin,
留下了一个看不见的回车怪兽\n。getline一进门,就被怪兽吓跑了!
❌ 错误示例
int age; string name; cin >> age; getline(cin, name); // 直接读到空行✅ 正确做法
cin >> age; cin.ignore(); // 吃掉回车 getline(cin, name);📜口诀:
cin 后用 getline,先把回车吃掉先!
🕳️ 坑 2:以为string能自动读空格(误会)😵
📖 故事
小朋友以为 string 什么都能读,
结果cin >> s也怕空格!
❌ 误会代码
string s; cin >> s; // 只能读到第一个词✅ 正确方式
getline(cin, s);📜口诀:
整句要用 getline!
🕳️ 坑 3:下标越界(城堡外的禁区)🚧
📖 故事
string 城堡虽然大,
但下标范围依然有界限!
❌ 错误示例
string s = "cat"; cout << s[10]; // 禁区!🧠 正确认知
合法下标:
0 ~ s.length()-1超出范围 →不可预料
📜口诀:
城堡再大,也有围墙!
🕳️ 坑 4:把length()当成最后一个下标 📏
📖 故事
有人以为:
“长度是 3,下标就到 3?”
❌ 错误理解
string s = "dog"; s[s.length()] = '!';✅ 正确理解
s.length()是字符个数最后一个下标是:
length() - 1
📜口诀:
长度不是下标,减一才到家!
🕳️ 坑 5:误用==(其实这是优点!)🤯
📖 故事
学过 char 数组的小朋友很紧张:
“不能用
==啊!”
❗ 真相
string a = "cat"; string b = "cat"; if (a == b) { // ✅ 正确! cout << "一样!"; }📌string 和 char 数组不同!
📜口诀:
string 比内容,等号可以用!
🕳️ 坑 6:忘记#include <string>📦
📖 故事
没有带魔法书,
string 魔法全部失效!
❌ 错误
string s = "Hi"; // 报错✅ 正确
#include <string>📜口诀:
string 魔法,先带书来!
🕳️ 坑 7:把find当成真假判断 🔍
📖 故事
小朋友以为:
“找不到就返回 0?”
❌ 错误示例
if (s.find("cat")) { cout << "找到了"; }✅ 正确用法
if (s.find("cat") != string::npos) { cout << "找到了"; }📜口诀:
find 找不到,npos 是信号!
🕳️ 坑 8:乱用substr(越界剪刀)✂️
📖 故事
剪刀太大,一刀剪出城堡外!
❌ 错误示例
string s = "abc"; cout << s.substr(2, 5); // 危险🧠 正确原则
起点不能超过长度
剪多少要合理
📜口诀:
剪字符串,别剪出界!
🕳️ 坑 9:频繁用+拼接(体力消耗)🔋
📖 故事
string 虽然聪明,
但一直拼接也会累(效率问题)。
❌ 不推荐写法(了解即可)
string s = ""; for (int i = 0; i < 10000; i++) { s = s + "a"; }✅ 更好的方式(了解即可)
string s; s.reserve(10000);📌小学生阶段:知道有坑即可
🕳️ 坑 10:以为 string 没有结尾字符 🧐
📖 故事
有人说:
“string 没有
\0吧?”
🧠 真相
string内部仍然有
'\0'只是你不用管
📜口诀:
string 有尾巴,只是你看不见!
🏆 string 安全使用“护身符口诀”🛡️
整句输入用 getline
cin 后记得吃回车
长度不是下标
find 要和 npos 比
string 城堡虽智能,边界规则别忘记
三、📘《string 专项练习 10 题(闯关式)》
🧒 适合对象:初学 C++ 的小学生
🏰 故事背景:string 王国闯关大冒险
🎯 目标:熟练掌握string的输入、访问、修改、查找、截取、比较等操作
🥉 第一关:string 新生报到(入门)
🧩 第 1 题:欢迎来到 string 王国 👑
📖 故事
新来的小朋友要向 string 国王报上自己的名字。
👉 要求
1️⃣ 定义一个string name
2️⃣ 使用getline输入名字(可能有空格)
3️⃣ 输出:
Welcome, xxx!✍️ 提示
👉 一定要用getline
🥉 第二关:字符小士兵(下标访问)
🧩 第 2 题:第一个字符是谁? 🔤
📖 故事
string 城堡的第一个士兵想知道自己是谁。
👉 要求
1️⃣ 输入一个字符串s
2️⃣ 输出它的第一个字符
✍️ 提示
👉 使用s[0]
🧩 第 3 题:最后一个字符的秘密 🕵️♂️
📖 故事
最后一个字符躲在城堡最里面。
👉 要求
1️⃣ 输入字符串s
2️⃣ 输出它的最后一个字符
✍️ 提示
👉s[s.length() - 1]
🥈 第三关:string 体检中心(长度 & 遍历)
🧩 第 4 题:字符串有多长? 📏
📖 故事
医生要检查 string 宝宝有多长。
👉 要求
1️⃣ 输入字符串s
2️⃣ 输出字符串长度
🧩 第 5 题:字符一个一个报数 🔢
📖 故事
string 城堡点名,每个字符都要站出来。
👉 要求
1️⃣ 输入字符串s
2️⃣ 使用for循环
3️⃣ 每行输出一个字符
✍️ 示例
输入:
cat输出:
c a t🥈 第四关:string 魔法变形术(修改)
🧩 第 6 题:变成大写勇士 ⚔️
📖 故事
小写字母要穿上大写盔甲!
👉 要求
1️⃣ 输入一个字符串(只含小写字母)
2️⃣ 把所有字母变成大写
3️⃣ 输出新字符串
✍️ 提示
👉'a' → 'A':减去'a' - 'A'
🥇 第五关:字符串侦探(查找)
🧩 第 7 题:有没有“cat”? 🐱
📖 故事
侦探要在字符串中寻找神秘的"cat"。
👉 要求
1️⃣ 输入字符串s
2️⃣ 如果包含"cat"输出YES
3️⃣ 否则输出NO
✍️ 提示
👉 使用find
👉 记得和string::npos比较
🧩 第 8 题:第一个空格在哪? ␣
📖 故事
空格精灵藏在字符串里。
👉 要求
1️⃣ 输入一行字符串
2️⃣ 输出第一个空格的位置
3️⃣ 如果没有空格,输出-1
🥇 第六关:字符串剪刀手(截取)
🧩 第 9 题:名字和姓氏 ✂️
📖 故事
string 小朋友叫 “Tom Lee”,
老师想分开名字和姓氏。
👉 要求
1️⃣ 输入一行字符串(名字 + 空格 + 姓氏)
2️⃣ 输出名字
3️⃣ 再输出姓氏
✍️ 提示
👉find(" ")
👉substr
🏆 终极关:string 守护者(综合)
🧩 第 10 题:密码检查员 🔐
📖 故事
string 王国要设置安全密码!
👉 要求
1️⃣ 输入一个字符串作为密码
2️⃣ 如果满足以下条件,输出OK,否则输出NO
✅ 条件:
长度 ≥ 6
包含字母
'a'
✍️ 提示
👉 用length()+find()
四、📘 string 专项练习 10 题参考程序
🥉 第一关:string 新生报到(入门)
🧩 第 1 题:欢迎来到 string 王国 👑
#include <iostream> #include <string> using namespace std; int main() { string name; cout << "请输入名字:"; getline(cin, name); // 小朋友报名字,可能有空格 cout << "Welcome, " << name << "!" << endl; return 0; }🥉 第二关:字符小士兵(下标访问)
🧩 第 2 题:第一个字符是谁? 🔤
#include <iostream> #include <string> using namespace std; int main() { string s; cout << "请输入字符串:"; getline(cin, s); if (!s.empty()) { cout << "第一个字符是:" << s[0] << endl; } else { cout << "字符串为空哦!" << endl; } return 0; }🧩 第 3 题:最后一个字符的秘密 🕵️♂️
#include <iostream> #include <string> using namespace std; int main() { string s; cout << "请输入字符串:"; getline(cin, s); if (!s.empty()) { cout << "最后一个字符是:" << s[s.length() - 1] << endl; } else { cout << "字符串为空哦!" << endl; } return 0; }🥈 第三关:string 体检中心(长度 & 遍历)
🧩 第 4 题:字符串有多长? 📏
#include <iostream> #include <string> using namespace std; int main() { string s; cout << "请输入字符串:"; getline(cin, s); cout << "字符串长度:" << s.length() << endl; return 0; }🧩 第 5 题:字符一个一个报数 🔢
#include <iostream> #include <string> using namespace std; int main() { string s; cout << "请输入字符串:"; getline(cin, s); cout << "逐个字符输出:" << endl; for (size_t i = 0; i < s.length(); ++i) { cout << s[i] << endl; } return 0; }🥈 第四关:string 魔法变形术(修改)
🧩 第 6 题:变成大写勇士 ⚔️
#include <iostream> #include <string> using namespace std; int main() { string s; cout << "请输入小写字母字符串:"; getline(cin, s); for (size_t i = 0; i < s.length(); ++i) { if (s[i] >= 'a' && s[i] <= 'z') { s[i] = s[i] - ('a' - 'A'); // 小写 → 大写 } } cout << "大写字符串:" << s << endl; return 0; }🥇 第五关:字符串侦探(查找)
🧩 第 7 题:有没有“cat”? 🐱
#include <iostream> #include <string> using namespace std; int main() { string s; cout << "请输入字符串:"; getline(cin, s); if (s.find("cat") != string::npos) { cout << "YES" << endl; } else { cout << "NO" << endl; } return 0; }🧩 第 8 题:第一个空格在哪? ␣
#include <iostream> #include <string> using namespace std; int main() { string s; cout << "请输入字符串:"; getline(cin, s); size_t pos = s.find(' '); if (pos != string::npos) { cout << pos << endl; } else { cout << -1 << endl; } return 0; }🥇 第六关:字符串剪刀手(截取)
🧩 第 9 题:名字和姓氏 ✂️
#include <iostream> #include <string> using namespace std; int main() { string fullName; cout << "请输入名字和姓氏:"; getline(cin, fullName); size_t pos = fullName.find(' '); if (pos != string::npos) { string firstName = fullName.substr(0, pos); string lastName = fullName.substr(pos + 1); cout << "名字:" << firstName << endl; cout << "姓氏:" << lastName << endl; } else { cout << "没有找到空格,无法分割" << endl; } return 0; }🏆 终极关:string 守护者(综合)
🧩 第 10 题:密码检查员 🔐
#include <iostream> #include <string> using namespace std; int main() { string password; cout << "请输入密码:"; getline(cin, password); if (password.length() >= 6 && password.find('a') != string::npos) { cout << "OK" << endl; } else { cout << "NO" << endl; } return 0; }✅小结(讲解重点)
getline→ 整行输入length(), size()→ 字符串长度[]→ 访问字符for→ 遍历每个字符find()→ 查找字符或子串substr()→ 截取子串字符串大小写修改可以用循环 + ASCII 运算
注意边界判断 (
empty(),npos)