【C++】 String 常用操作:增删查改 | 查找 | 截取 | IO

📌 相关专栏

很高兴你点开这篇文章✨

这里会持续更新我喜欢的内容,关注我,一起慢慢变好呀

👍 点赞 ⭐ 收藏 💬 评论


文章目录

  • 前言
  • [1. 尾部追加:+= / push_back / append](#1. 尾部追加:+= / push_back / append)
  • [2. 指定位置插入:insert](#2. 指定位置插入:insert)
  • [3. 指定位置删除:erase](#3. 指定位置删除:erase)
  • [4. 字符串替换:replace](#4. 字符串替换:replace)
  • [5. 字符串查找:find](#5. 字符串查找:find)
  • [6. 子串截取:substr](#6. 子串截取:substr)
  • [7. C风格转换:c_str](#7. C风格转换:c_str)
  • [8. 整行输入:getline](#8. 整行输入:getline)
  • 总结
  • 本文所有代码
    • [🐾 test.cpp](#🐾 test.cpp)

前言

C++ 的 std::string 不仅提供了基础的存储和遍历功能,还封装了大量实用的字符串操作接口------追加、插入、删除、替换、查找、截取等。熟练掌握这些接口,可以让我们在处理字符串时避免自己造轮子,写出更简洁、更安全的代码。

🐶 🐾 ✨ 🐾 🐶


1. 尾部追加:+= / push_back / append

string 提供了三种常见的尾部追加方式:

cpp 复制代码
string s1("hello qianyv");

// 1. push_back:追加单个字符
s1.push_back('a');
cout << s1 << endl;   // hello qianyva

// 2. append:追加多个相同字符 或 字符串
s1.append(10, 'x');   // 追加10个 'x'
cout << s1 << endl;

s1.append("abc");     // 追加字符串 "abc"
cout << s1 << endl;

// 3. += 运算符(最推荐,写法简洁)
string s2("nihao qianyv");
s2 += ' ';            // 追加单字符
s2 += "hello";        // 追加字符串
cout << s2 << endl;   // nihao qianyv hello

注意 :三种方式中,+= 运算符最直观,推荐日常使用。push_back 适合单字符追加,append 适合批量追加。

🐶 🐾 ✨ 🐾 🐶


2. 指定位置插入:insert

insert 可以在任意位置插入字符或字符串,有多种重载形式:

cpp 复制代码
string s2("hello qianyv");

// 头插字符串
s2.insert(0, "nihao");
cout << s2 << endl;   // nihaohello qianyv

// 指定位置之前插入字符串
s2.insert(2, "ma");
cout << s2 << endl;   // nima haohello qianyv

// 插入 n 个相同字符
s2.insert(7, 1, 'b');
cout << s2 << endl;   // nima haobhello qianyv

// 使用迭代器插入(头插单字符)
s2.insert(s2.begin(), ' ');
cout << s2 << endl;   //  nima haobhello qianyv

注意 :insert(pos, n, char) 中 n=1 时相当于插入单字符,但不能省略 n 参数。迭代器版本的 insert 可以与 begin()/end() 配合使用。

🐶 🐾 ✨ 🐾 🐶


3. 指定位置删除:erase

erase 用于删除指定位置或指定范围的字符:

cpp 复制代码
string s3("nihao hello qiany");

// 头删:删除下标 0 位置开始的 1 个字符
s3.erase(0, 1);
cout << s3 << endl;   // ihao hello qiany

// 尾删:删除最后一个字符
s3.erase(s3.size() - 1, 1);
cout << s3 << endl;   // ihao hello qian

// 删除多个字符:从下标 3 开始删 5 个
s3.erase(3, 5);
cout << s3 << endl;   // iha qian

// 只给一个参数:从该位置删到末尾
s3.erase(3);
cout << s3 << endl;   // iha

注意 :erase(pos, len) 中 len 的缺省值是 npos(通常为 -1),代表删除到末尾。也可以用迭代器版本:erase(begin()) 头删,erase(end() - 1) 尾删。

🐶 🐾 ✨ 🐾 🐶


4. 字符串替换:replace

replace 可以替换指定位置的字符或子串:

cpp 复制代码
string s4("hello qianyv");

// 将下标 5 位置的 1 个字符替换成 "a"
s4.replace(5, 1, "a");
cout << s4 << endl;   // hello a qianyv

// 将下标 5 位置的 1 个字符替换成 "***"(少换多,会涉及字符移动)
s4.replace(5, 1, "***");
cout << s4 << endl;   // hello *** qianyv

实战 :将所有空格替换为 *

cpp 复制代码
// 方法1:使用 find + replace
string s5("hello world a b c d");
size_t pos = s5.find(" ");
while (pos != string::npos) {
    s5.replace(pos, 1, "*");
    pos = s5.find(" ", pos + 1);
}
cout << s5 << endl;   // hello*world*a*b*c*d

// 方法2:空间换时间(更高效)
string s6("hello world a b c d");
string tmp;
tmp.reserve(s6.size());   // 预分配空间,避免频繁扩容
for (auto ch : s6) {
    if (ch == ' ')
        tmp += '*';
    else
        tmp += ch;
}
s6.swap(tmp);             // 交换,比 s6 = tmp 更高效
cout << s6 << endl;       // hello*world*a*b*c*d

注意 :replace 适合少量替换;大量替换时,用"空间换时间"的方法(遍历+追加到新串)效率更高,配合 reserve 预分配空间可进一步优化。swap 比直接赋值效率高(只交换内部指针)。

🐶 🐾 ✨ 🐾 🐶


5. 字符串查找:find

find 用于查找字符或子串,返回第一次出现的位置,找不到则返回 string::npos:

cpp 复制代码
string s5("nihao qianyv");

// 查找字符 'o'
size_t pos1 = s5.find('o');
if (pos1 != string::npos) {
    cout << "'o'在位置:" << pos1 << endl;   // 'o'在位置:3
}

// 查找子串 "qianyv"
size_t pos2 = s5.find("qianyv");
if (pos2 != string::npos) {
    cout << "qianyv在位置:" << pos2 << endl; // qianyv在位置:6
}

// 从下标 5 开始查找字符 'o'
size_t pos3 = s5.find('o', 5);
cout << "'o'在位置:" << pos3 << endl;       // 找不到,返回 npos(通常为 -1)

注意 :string::npos 是 size_t 类型的最大值(通常为 -1 的无符号表示),作为"未找到"的返回值。第二个参数指定起始搜索位置。

🐶 🐾 ✨ 🐾 🐶


6. 子串截取:substr

substr(pos, len) 从 pos 位置开始截取 len 个字符,不指定 len 则截取到末尾:

cpp 复制代码
string s6 = "nihao qianyv";

// 从下标 5 开始,取到末尾(不传第二个参数)
string sub1 = s6.substr(5);
cout << sub1 << endl;   // " qianyv"(注意前面有个空格)

// 从下标 2 开始,取到末尾
string sub2 = s6.substr(2);
cout << sub2 << endl;   // "hao qianyv"

注意 :substr 不会修改原字符串,而是返回一个新字符串。第二个参数若超过字符串长度,会自动截取到末尾。

🐶 🐾 ✨ 🐾 🐶


7. C风格转换:c_str

c_str() 返回一个 const char* 指针,指向以 '\0' 结尾的 C 风格字符串,用于适配 C 语言库函数:

cpp 复制代码
#include <cstring>

string s7 = "nihao qianyv";

// 1. printf 输出(printf 不直接支持 string)
printf("%s\n", s7.c_str());   // nihao qianyv

// 2. 调用 C 库函数 strlen
size_t len = strlen(s7.c_str());
cout << len << endl;          // 13

注意 :当需要与 C 语言接口(如 printf、strlen、文件操作等)交互时,c_str() 必不可少。返回的指针指向内部字符数组,但不应修改它。

🐶 🐾 ✨ 🐾 🐶


8. 整行输入:getline

cin >> string 或 scanf 读取字符串时,遇到空格就会停止。getline 可以读取一整行(包括空格):

cpp 复制代码
void test_string8() {
    string s9;
    // 不传第三个参数则默认以换行符结束
    // 下面指定终止符为 '*',遇到 '*' 才停止读取
    getline(cin, s9, '*');
}

注意 :getline 的第三个参数可以指定自定义终止符(默认是 '\n')。它可以读取带空格的整行内容,常用于处理用户输入的完整句子。

🐶 🐾 ✨ 🐾 🐶


总结

操作 核心接口
尾部追加 +=、push_back、append
插入 insert
删除 erase
替换 replace
查找 find
截取 substr
C风格转换 c_str
整行输入 getline

🐶 🐾 ✨ 🐾 🐶


本文所有代码

🐾 test.cpp

cpp 复制代码
#define _crt_secure_no_warnings 1
#include<iostream>
#include<string>
using namespace std;

////尾部追加
////尾部追加---operator +=/push_back/append

void test_string1()
{
	string s1("hello qinayv");

	s1.push_back('a');				//push_back->尾插单字符
	cout << s1 << endl;

	s1.append(10, 'x');				//尾插10个x
	cout << s1 << endl;

	s1.append("abc");				//尾插字符串"abc"
	cout << s1 << endl << endl;


	string s2("nihao qianyv");		//用 += 更方便
	s2 += ' ';
	s2 += "hello";
	cout << s2 << endl;

}

int main()
{
	test_string1();
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////
////插入和删除---inser指定位置插入

void test_string2()
{
	string s2("hello qianyv");

	//inser(pos,"")--------->pos是下标
	//头插
	s2.insert(0, "nihao");
	cout << s2<< endl;

	//指定位置之前插入
	s2.insert(2, "ma");
	cout << s2 << endl;

	//string& inser(size_t pos,size_t n,char c)
	//n>1时插入n个字符,n=1时相当于插入单个字符,但不能没有n;
	
	s2.insert(7, 1, 'b');
	cout << s2<< endl;

	s2.insert(s2.begin(), ' ');
	cout << s2 << endl;

}

int main()
{
	test_string2();
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
 
////插入和删除---erase:指定位置删除
void test_string3()
{
	string s3("nihao hello qiany");
	cout << s3 << endl;
	
	//删除数据
	//string& erase(size_t pos = 0, size_t len = npos);
	//iterator erase(iterator p);---迭代器用法
	
	//头删数据
	//erase(pos,n)->pos:下标;n:个数
	s3.erase(0, 1);				//迭代器用法:erase(begin());
	cout << s3 << endl<<endl;			

	//尾删数据
	s3.erase(s3.size() - 1, 1);//迭代器用法:erase(end());
	cout << s3 << endl<<endl;

	//删除多个数据
	s3.erase(3, 5);
	cout << s3 << endl;
	s3.erase(3);//若不给第二个实参,则len默认给缺省值npos,即删除对应位置后面的全部数据
	cout << s3 << endl;
}
int main()
{
	test_string3();
	return 0;
}

////////////////////////////////////////////////////////////////////////////////////

//字符串替换:replace()->修改指定位置的内容
void test_string4()
{
	string s4("hello qianyv");
	cout << s4 << endl<<endl;

	s4.replace(5, 1,"a");
	cout << s4 << endl<<endl;

	s4.replace(5, 1,"***");//将下标为5位置的字符替换为***,由于是少的字符替换成多字符
							//说明需要到前面insert的逻辑讲后面的字符往后移动

	//练习:将所有空格替换为*
	// 
	//1.用find()查找
	string s5("hello       world    a b c   d");
	size_t pos = s5.find(" ");
	while (pos != string::npos)
	{
		s5.replace(pos, 1, "*");
		pos = s5.find(" ", pos + 1);

	}
	cout << s5 <<endl;


	//但是我们发现上面这种方法会比较麻烦,每次只能找一个空格替换成*

	//2.空间换时间
	string s6("hello       world    a b c   d");
	string tmp;
	tmp.reserve(s6.size());
	for (auto ch : s6)
	{
		if (ch == ' ')
		{
			tmp += '*';
		}
		else
		{
			tmp += ch;
		}
	}

	//s6=tmp;---最后赋值给s6
	//也可以使用string中的swap
	s6.swap(tmp);
	cout << s6 << endl;
}

int main()
{
	test_string4();
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////
////字符串查找---find():找字符/子串
void test_string5()
{
	string s5("nihao qianyv");

	//找字符:'o'
	size_t pos1 = s5.find('o');
	if (pos1 != string::npos)
	{
		cout << "'o'在位置:" << pos1 << endl << endl;
	}
	
	//找字串:"qianyv"
	size_t pos2 = s5.find("qianyv");
	if (pos2 != string::npos)
	{
		cout << "qianyv在位置:" << pos2 << endl<<endl;
	}

	//从下标n开始找字符'o'
	size_t pos3 = s5.find('o', 5);
	cout << "'o'在位置:" << pos3 << endl << endl;

}

int main()
{
	test_string5();
	return 0;
}

////////////////////////////////////////////////////////////////////////////////////////

/////字串截取---substr():从指定位置取指定长度
void test_string6()
{
	string s6 = "nihao qianyv";

	//1.从第6个位置开始,取5个字符
	string sub1 = s6.substr(5);
	cout << sub1 << endl<<endl;			// qianyv  (前面是个空格)

	//2.从位置2开始,取到末尾------没给第二个参数
	string sub2 = s6.substr(2);			//hao qianyv
	cout << sub2 << endl;
}

int main()
{
	test_string6();
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////

////c字符转换---c_str():用来适配c语言库函数

#include<cstring>
void test_string7()
{
	string s7 = ("nihao qianyv");

	//1.printf输出(printf不直接支持string,要转换)
	printf("%s\n", s7.c_str());

	//2.调用c库函数strlen---需要包含头文件 <cstring>
	size_t len = strlen(s7.c_str());
	cout << len << endl << endl;
}

int main()
{
	test_string7();
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////

//整行输入---getline():读取带空格的字符,能读取一整行
//   cin>>string或scanf 读取字符时,读到空格就会停止,getline不会

void test_string8()
{
	string s9;			//空串

	//不传第3个实参则默认回车结束,可以指定终止符,下面指定终止符是*
	getline(cin, s9, '*');
}

int main()
{
	test_string8();
	return 0;
}
  1. 欢迎留言交流
  2. 期待你的评论与建议
  3. 留下你的想法吧

谢谢你看到这里呀

如果喜欢这篇内容,点个关注,下次更新不迷路✨

👍 点赞 ⭐ 收藏 💬 评论

相关推荐
长栎1 小时前
面试官说你的单例线程不安全,你真能现场修好?
java
xian_wwq1 小时前
【学习笔记】「大模型安全:攻击面演化史」第 04 篇-模型窃取与供应链安全
笔记·学习·ai安全
十月的皮皮1 小时前
C语言学习笔记20260607-判断一个数是否为2的n次方(三种方法)
c语言·笔记·学习
码云骑士1 小时前
【Java基础】JDK安装常见问题教辅-从踩坑到排雷
java·开发语言
tedcloud1231 小时前
FluentFlyout部署教程:打造更美观的Windows桌面环境
数据库·人工智能·sql·学习·自动化
nashane1 小时前
HarmonyOS 6学习:指南针“文图反向”Bug修复——从“北偏东”变“北偏西”的坐标系纠错
学习·华为·bug·harmonyos
jelly酱1 小时前
Qt 坐标体系入门:从 GUI 概念到坐标实践
c++
代码改善世界1 小时前
【C++进阶】哈希表封装unordered_map和unordered_set
c++·哈希算法·散列表
Sunia1 小时前
《AgentX 专栏》09-MCP协议双向打通:让AgentX既能被Claude调用又能调度全球工具生态
java·架构