C++ STL string(字符串)学习笔记

前言

string 是 C++ STL 中封装字符串的类,提供了丰富的接口用于字符串的创建、访问、拼接、修改、查找等操作。相比 C 风格字符串(char*),string 自动管理内存,更安全、更方便。

本文基于个人练习代码整理,将零散的测试函数按功能重命名并加上详细注释,方便回顾。


1. 字符串的创建与初始化

功能说明

学习如何创建和初始化 string 对象,包括:

  • 直接初始化
  • 拷贝初始化
  • 用 C 风格字符串初始化
  • 用重复字符初始化

代码示例(含详细注释)

cpp 复制代码
// 字符串的创建与初始化
void string_creation_and_initialization() {
    string s1 = "唐三";            // 直接初始化
    cout << "s1: " << s1 << endl;

    string s2(s1);                 // 拷贝构造
    cout << "s2: " << s2 << endl;

    string s3 = s1;                // 赋值初始化
    cout << "s3: " << s3 << endl;

    string s4("hello");            // 用C风格字符串初始化
    cout << "s4: " << s4 << endl;

    string s5 = "hello";           // 用C风格字符串直接赋值
    cout << "s5: " << s5 << endl;

    string s6(3, 'a');             // 用3个字符 'a' 初始化
    cout << "s6: " << s6 << endl;

    string s7 = string("world");   // 显式构造
    cout << "s7: " << s7 << endl;

    string s8(string("唐三"));     // 拷贝构造(显式写法)
    cout << "s8: " << s8 << endl;
}

初始化方式总结

初始化方式 示例 说明
直接初始化 string s = "abc"; 使用 = 直接赋值字符串字面量
拷贝构造 string s2(s1); 使用另一个 string 初始化
C 风格字符串构造 string s("abc"); const char* 初始化
重复字符构造 string s(5, 'a'); 创建由 5 个 'a' 组成的字符串

2. 字符串输入方式

功能说明

学习两种常见的字符串输入方法:

  • cin >> s;:遇到空格或换行停止
  • getline(cin, s);:可以读取一整行(包括空格)

代码示例

cpp 复制代码
// 用 cin 读取字符串(不含空格)
void string_input_with_cin() {
    string s1;
    cout << "请输入字符串(cin,空格结束):";
    cin >> s1;
    cout << "你输入的是:" << s1 << endl;
}

// 用 getline 读取整行(含空格)
void string_input_with_getline() {
    string s1;
    cout << "请输入字符串(getline,可含空格):";
    getline(cin, s1);
    cout << "你输入的是:" << s1 << endl;
}

注意事项

  • cin >> s; 适合读取单个单词
  • getline(cin, s); 适合读取整行文本
  • 如果 getline 前有 cin >> var;,需要处理换行符:cin.ignore()

3. 字符串比较

功能说明

string 重载了比较运算符(==, !=, <, <=, >, >=),按字典序(ASCII 码)比较。

代码示例

cpp 复制代码
void string_comparison() {
    string s1 = "abc";
    string s2 = "edf";

    if (s1 < s2) {
        cout << "s1 < s2" << endl;
    } else {
        cout << "s1 >= s2" << endl;
    }
}

比较规则

  • 按字符依次比较 ASCII 码值
  • 如果一个是另一个的前缀,短的更小(如 "app" < "apple"

4. 字符串连接

功能说明

  • 使用 + 运算符拼接
  • 使用 += 运算符追加

代码示例

cpp

运行

复制代码
void string_concatenation() {
    string s1 = "123456", s2 = "abcdef", s3;

    s3 = s1 + s2;  // 拼接两个字符串
    cout << "s1 + s2 = " << s3 << endl;

    s1 += s2;      // 追加到末尾
    cout << "s1 += s2 = " << s1 << endl;

    // 注意:两个字符串字面量不能直接相加
    // string s4 = "xiaoming" + "china"; // ❌ 编译错误
    string s4 = string("xiaoming") + "china"; // ✅ 正确
    cout << s4 << endl;
}

5. 字符串遍历

功能说明

常见遍历方式:

  • 下标 []
  • 范围 for 循环(C++11)
  • 迭代器

代码示例

cpp 复制代码
void string_traversal() {
    string s = "abcdefghijk";

    // 1. 范围 for(C++11)
    cout << "范围 for 遍历: ";
    for (auto c : s) {
        cout << c << " ";
    }
    cout << endl;

    // 2. 下标访问
    cout << "下标访问遍历: ";
    for (int i = 0; i < s.size(); i++) {
        cout << s[i] << " ";
    }
    cout << endl;

    // 3. 迭代器
    cout << "迭代器遍历: ";
    for (auto it = s.begin(); it != s.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}

6. 子串操作(substr)

功能说明

substr(pos, len):从位置 pos 开始截取长度为 len 的子串。

代码示例

cpp 复制代码
void string_substr() {
    string s = "value";

    string s1 = s.substr();         // 截取全部
    cout << "s1: " << s1 << endl;

    string s2 = s.substr(3);        // 从下标3到末尾
    cout << "s2: " << s2 << endl;

    string s3 = s.substr(s.size()); // 从末尾开始(空字符串)
    cout << "s3: " << s3 << endl;

    string s5 = s.substr(2, 3);     // 从下标2开始,长度3
    cout << "s5: " << s5 << endl;

    string s7 = s.substr(3, 10);    // 长度超出范围则到末尾
    cout << "s7: " << s7 << endl;
}

7. 插入操作(insert)

功能说明

insert 可以在指定位置插入字符、字符串或区间。

代码示例

cpp 复制代码
void string_insert() {
    string s1 = "value";

    s1.insert(s1.begin(), 's'); // 在开头插入 's'
    cout << s1 << endl; // svalue

    s1.insert(s1.begin(), 3, 'a'); // 在开头插入 3 个 'a'
    cout << s1 << endl; // aaasvalue

    s1.insert(s1.begin(), s1.begin(), s1.begin() + 2); // 插入一段区间
    cout << s1 << endl;

    s1.insert(s1.end(), {'e', 'f'}); // 插入初始化列表
    cout << s1 << endl;
}

8. 删除操作(erase)

功能说明

erase 可以删除指定位置、区间或整个字符串。

代码示例

cpp 复制代码
void string_erase() {
    string s1 = "value";
    s1.erase(); // 清空字符串
    cout << "s1: " << s1 << endl;

    string s2 = "value";
    s2.erase(1, 3); // 从下标1开始删除3个字符
    cout << "s2: " << s2 << endl; // ve

    string s3 = "value";
    s3.erase(s3.begin() + 1); // 删除迭代器位置字符
    cout << "s3: " << s3 << endl; // vlue

    string s4 = "value";
    s4.erase(s4.begin(), s4.begin() + 2); // 删除区间
    cout << "s4: " << s4 << endl; // lue
}

9. 替换操作(replace)

功能说明

replace(pos, len, ...):从位置 pos 开始,替换长度为 len 的部分。

代码示例

cpp 复制代码
void string_replace() {
    string s = "I very love China";
    const char* cp1 = "truly";
    const char* cp2 = "truly!!!!!";

    string str1 = "really";
    string str2 = "really!";

    s.replace(2, 4, cp1); // 从下标2开始,替换4个字符为 "truly"
    cout << s << endl;

    s.replace(2, 5, cp1);
    cout << s << endl;

    s.replace(2, 5, str1);
    cout << s << endl;

    s.replace(2, 6, str2, 0, 6); // 替换为 str2 的子串
    cout << s << endl;

    s.replace(2, 6, 3, '*'); // 替换为 3 个 '*'
    cout << s << endl;
}

10. 追加操作(append)

功能说明

append 用于在字符串末尾追加内容。

代码示例

cpp 复制代码
void string_append() {
    string s1 = "C++";
    s1.append(" program"); // 追加字符串
    cout << s1 << endl; // C++ program
}

11. 实战:删除字符串中的标点符号

功能说明

使用 ispunct() 判断标点符号,并过滤掉。

代码示例

cpp 复制代码
#include <cctype> // ispunct 函数需要

void string_remove_punctuation() {
    cout << "请输入字符串:";
    string s;
    getline(cin, s);

    for (auto c : s) {
        if (!ispunct(c)) { // 如果不是标点符号则输出
            cout << c;
        }
    }
    cout << endl;
}

12. string 常用操作速查表

操作 方法 示例
长度 size() / length() s.size()
判空 empty() if (s.empty())
访问 [] / at() s[0], s.at(0)
拼接 + / += / append() s + "abc", s.append("xyz")
子串 substr(pos, len) s.substr(2, 3)
插入 insert(pos, ...) s.insert(2, "abc")
删除 erase(pos, len) / erase(it) s.erase(1, 2)
替换 replace(pos, len, ...) s.replace(1, 2, "xx")
查找 find() / rfind() s.find("abc")
比较 ==, !=, <, <=, >, >= s1 < s2
输入 cin >> s / getline(cin, s) -
输出 cout << s -

总结

  • string 是可变长度的字符序列,自动管理内存
  • 支持丰富的操作:增删改查、比较、拼接、子串等
  • 遍历方式多样:下标、范围 for、迭代器
  • 注意 getlinecin 的区别,以及 ispunct 等字符判断函数的使用

C++ string 成员函数思维导图

最后附上我自己练习时的源码资料(有兴趣的可以按自己喜好自由练习修改):

头文件:

cpp 复制代码
#pragma once
#include <string>
#include <iostream>
#include <vector>
#include <math.h>

using namespace std;

/*
	声明函数方法
*/

//隔开函数
void gekai();
void test01();
void test02();
void test03();
void test04();
void test05();
void test06();
void test07();
void test08();
void test09();

//erase()删除函数使用
void test10();

//append()方法
void test11();

//
void test12();
//输入一串带有标点符号的字符串,去除字符串中的标点符号!
void judgmentPunctuation();

源文件:

cpp 复制代码
#include "string.h"


/*
	实现函数方法
*/
void judgmentPunctuation() {
	//string s;
	//cin >> s;
	//int flag = 0;

	////开始判断
	////for (auto i = s.begin(); i != s.end(); i++) {

	////}
	//for (int i = 0; i < s.size(); i++) {
	//	if ((bool)ispunct(s[i])) {
	//		flag = i;
	//		s.erase(flag);
	//	}
	//}
	//cout << s << endl;

	//方法二
	cout << "请输入字符串:";
	string s;
	getline(cin, s);
	for (auto c : s) {
		if (!ispunct(c)) {
			cout << c;
		}
	}
}

void test12() {
	string s = "I very love China";
	const char* cp1 = "truly";
	const char* cp2 = "truly!!!!!";

	string str1 = "really";
	string str2 = "really!";

	s.replace(2, 4, cp1);
	cout << s << endl;

	s.replace(2, 5, cp1);
	cout << s << endl;

	s.replace(2, 5, str1);
	cout << s << endl;

	s.replace(2, 6, str2,0,6);
	cout << s << endl;

	s.replace(2, 6, 3, '*');
	cout << s << endl;
}

void test11() {
	string s1 = "C++";
	s1.append(" program");
	cout << s1 << endl;
}

void test10() {
	string s1 = "value";
	string s2 = "value";
	string s3 = "value";
	string s4 = "value";
	s1.erase();
	cout << "s1" << s1 << endl;

	s2.erase(1, 3);//ve
	cout <<"s2" << s2 << endl;

	s3.erase(s3.begin() + 1);//vlue
	cout << "s3" << s3 << endl;

	s4.erase(s4.begin(), s4.begin() + 2);//lue
	cout << "s4" << s4 << endl;
}

void test09() {
	string s1 = "value";
	s1.insert(s1.begin(), 's');
	cout << s1 << endl;//svalue

	s1.insert(s1.begin(), 3, 'a');
	cout << s1 << endl;//aaasvalue

	s1.insert(s1.begin(), s1.begin(), s1.begin()+2);
	cout << s1 << endl;

	s1.insert(s1.end(), { 'e','f' });
	cout << s1 << endl;


}

//取子串函数测试函数
void test08() {
	string s = "value";
	string s1 = s.substr();
	cout << "s1:" << s1 << endl;

	string s2 = s.substr(3);//ue
	cout << "s2:" << s2 << endl;

	//gekai();
	string s3 = s.substr(s.size());
	cout << "s3:" << s3 << endl;

	//string s4 = s.substr(10);
	//cout << s4 << endl;

	string s5 = s.substr(2, 3);//lue
	cout << "s5:" << s5 << endl;

	//string s6 = s.substr(6, 2);
	//cout << s6 << endl;

	string s7 = s.substr(3, 10);//ue
	cout << "s7:" << s7 << endl;

	string s8 = s.substr(5, 10);
	cout << "s8:" << s8 << endl;
}

void test07() {
	string s1 = "hello";
	string s2(s1, 1);
	cout << s2 << endl;//ello
	try {
		string s3(s1, 8);
		cout << s3 << endl;
	}
	catch (exception e) {
		//e.what();
		cout << "出错了!!!赶快改bug!!!" << endl;
	}

	string s4(s1, 5);
	cout << s4 << endl;

	string s5(s1, 0, 3);//hel
	cout << s5 << endl;

	string s6(s1, 2, 100);//ll0
	cout << s6 << endl;

	string s7(s1, 5, 3);//空字符
	cout << s7  << endl;

	try {
		string s8(s1, 6, 2);
		cout << s8 << endl;;
	}
	catch (exception e) {
		//e.what();
		cout << "出错了!!!赶快改bug!!!" << endl;
	}

}

void test06() {
	string s1 = "abcdefghijk";
	//C++ 11 新特性
	for (auto c : s1) {
		cout << c << " ";
	}
	cout << endl;
	cout << s1[0] << endl;
	cout << s1 << endl;

	for (int i = 0; i < s1.size(); i++) {
		cout << s1[i] << " ";
	}
	cout << endl;

	//使用迭代器(本质是指针)
	for (auto i = s1.begin(); i != s1.end(); i++) {
		cout << *i << " ";
	}
	gekai();
	string s8(s1, 100);
	cout << s8 << endl;
}

//字符串连接
void test05() {
	string s1 = "123456", s2 = "abcdef", s3;
	s3 = s1 + s2;
	cout << s3 << endl;

	//bug代码 const只读常量不能修改
	//string s4 = "xiaoming" + "china";
	//cout << s4 << endl;

}

void test04() {
	string s1 = "abc";
	string s2 = "edf";
	//字符串比较大小实用的是ASCll码比较
	if (s1 < s2) {	
		cout << "s1<s2" << endl;
	}
	else {
		cout << "s1>s2" << endl;
	}
}

void test03() {
	string s1;
	getline(cin, s1);	//可以接收带空格的字符串
	cout << s1 << endl;
}


void test02() {
	string s1;
	cin >> s1;//不可以接收带空格的字符串,遇到空格就会终止接收字符
	cout << s1 << endl;


}

void test01() {
	string s1="唐三";
	cout << s1 << endl;

	string s2(s1);
	cout << s2 << endl;

	string s3 = s1;
	cout << s3 << endl;

	string s4("hello");
	cout << s4 << endl;

	string s5 = "hello";
	cout << s5 << endl;

	string s6(3, 'a');
	cout << s6 << endl;

	string s7 = string("world");
	cout << s7 << endl;

	string s8(string("唐三"));
	cout << s8 << endl;



}

void gekai() {
	cout << endl << "######################################" << endl;
}
相关推荐
CS_Zero3 小时前
【开发工具】Windows10&11远程Ubuntu18及以上桌面
笔记·ubuntu
AA陈超3 小时前
虚幻引擎5 GAS开发俯视角RPG游戏 P04-12 可缩放浮点数的曲线表
c++·游戏·ue5·游戏引擎·虚幻
旭意3 小时前
C++微基础备战蓝桥杯之数组篇10.1
开发语言·c++·蓝桥杯
LGL6030A3 小时前
数据结构学习(2)——多功能链表的实现(C语言)
数据结构·学习·链表
iconball3 小时前
个人用云计算学习笔记 --18(NFS 服务器、iSCSI 服务器)
linux·运维·笔记·学习·云计算
肥肠可耐的西西公主4 小时前
后端(JavaWeb)学习笔记(CLASS 1):maven
笔记·学习·maven
kfepiza4 小时前
Spring的三级缓存原理 笔记251008
笔记·spring·缓存
青草地溪水旁4 小时前
VSCode C/C++ 构建任务配置文件 `tasks.json` 全字段深度解析
c语言·c++·vscode
DKPT6 小时前
JVM栈溢出和堆溢出哪个先满?
java·开发语言·jvm·笔记·学习