C++---string类
一、什么是string类
std::string
是 C++ 标准库(STL)提供的字符串类,用于方便地处理字符序列(文本)。它是 basic_string<char>
的别名,封装了动态字符数组的管理,提供了一系列字符串操作方法。
二、基本用法
1、构造(初始化)
string s1("hehehe");
2、拷贝构造
string s2(s1);
s2 = s1
3、operator= 重载
string s3;
s3 = s1;
4、size和lenth
size和length求字符串长度,两者在string处功能相同,不包含"\0"
cout << s1.size() << endl;
cout << s1.length() << endl;
//处处结果为s1字符串的长度
5、max_size
max_size: 所能开辟的最大空间,不常用
cout << s1.max_size() << endl;
//vs上的输出结果为9223372036854775807
6、resize
resize:改变原字符串,可加可减
size_t sz1 = s1.size();
s1.resize(sz1 + 2, 'a');//在原字符串后边追加两个字符
cout << s1 << endl;
size_t sz2 = s2.size();
s2.resize(sz2 - 1);//减去原字符串上的一个字符
7、capacity
capacity:容量,空间
cout << s1.capacity() << endl;
//输出编译器为字符串开辟的空间
8、reserve
reserve(n):如果 n > capacity,capacity就会扩大到n或更大;
如果n < capacity,capacity的变化不确定,取决于编译器,在vs中capacity不会缩小
reserve对capacity的增缩,不会影响字符串的长度,不会改变字符串
s1.reserve(100);
cout << s1 << endl;
cout << s1.capacity() << endl;
9、clear
clear: 清除字符串,不会改变容量大小
s2.clear();
//s2的空间大小不变,但是size变为0
10、empty
empty:判断长度是0
cout << s1.empty() << endl;
cout << s2.empty() << endl;
//字符串为空返回1,不为空返回0
11、shrink_to_fit
shrink_to_fit:让capacity去迎合size,但不一定等于size,缩容
s1.shrink_to_fit();
12、operator[ ]
operator[]: 改变字符串中的数据
s1[1] = 'x';
//原数组:hello world
//修改后:hxllo world
13、at
at:返回下标位置的字符
char a = s1.at(5);
14、back
back:返回字符串的最后一个字符
char b1 = s1.back();
15、front
front:返回字符串的第一个字符
char b2 = s1.front();
三、迭代器
迭代器(Iterator) 是一种设计模式,也是一种对象,用于顺序访问集合中的元素,而无需暴露其底层实现。它提供了一种统一的方式来遍历不同的数据结构(如数组、链表、树等),无论它们的内部结构如何。
string s("hello world");
1、begin
begin():指向字符串的第一个字符
cout << *s.begin() << endl;
//输出:h
2、end
end():指向'\0'
cout << *(s.end() - 1) << endl;
//输出:d
3、rbegin
rbegin:指向最后一个字符
cout << *s.rbegin() << endl;
//输出:d
4、rend
rend:指向字符串的前一个位置,不可访问不可解引用,可用作遍历
由于rend无法解引用,所以下边这种写法是错误的
cout << *(s.rend() + 1) << endl; //!!!错误
使用rend反向遍历字符串
for (auto it = s.rbegin(); it != s.rend(); ++it)
{cout << *it;
}
//输出:dlrow olleh
5、cbegin和cend
cbegin: const_iterator cbegin() const noexcept,只读,不能修改,指向第一个字符
cend: const_iterator cend() const noexcept,只读,不能修改,指向'\0'
cout << *s.cbegin() << endl;
cout << *(s.cend() - 1) << endl;
6、crbegin和crend
crbegin:const_reverse_iterator crbegin() const noexcept,指向最后一个字符
crend:const_reverse_iterator crend() const noexcept,指向第一个字符之前的一个位置
cout << *s.crbegin() << endl;
//cout << *(s.crend() + 1) << endl;!!!错误
注意:crend和rend一样不能解引用,不能访问
7、迭代器遍历字符串
string::iterator it = s.begin();
while (it!= s.end())
{cout << *it << " ";++it;
}
8、范围for
范围for:自动识别类型并打印,底层调用迭代器遍历
for (auto ch : s)
{cout << ch << ' ';
}
四、重铸
string s1("hello world");
1、operator+=
operator+=:重载+=,在后边插入单个字符或字符串,相当于尾插
s1 += 'a';
cout << s1 << endl;
//输出:hello worlda
s1 += "abcd";
cout << s1 << endl;
//输出:hello worldabcd
2、append
append:尾插,有多个接口,支持迭代器
①插入string
string s2("xixi");
s1.append(s2);
cout << s1 << endl;
//输出:hello worldxixi
②append(s, pos, n)
s1.append(s2, 1, 2);
cout << s1 << endl;
//输出:hello worldix
把s2中包含下标为1的及其后边的一共两个字符追加到s1,不写默认到s2结束,大于s2的字符串长度,就到s2结束
③追加字符串
s1.append("hehe");
cout << s1 << endl;
//输出:hello worldhehe
④append(n, c)
在s后边追加n个字符c
s1.append(3, 'a');
//输出:hello worldaaa
3、push_back
push_back:尾插一个字符
s1.push_back('b');
cout << s1 << endl;
//输出:hello worldb
4、assign
assign:用新的字符串替换原数据
①assign(s)
s1.assign(s2);
cout << s1 <<endl;
//输出:xixi
②assign(s, pos, n)
从包含s[pos]往后的n个字符替代s1原字符
s1.assign(s2, 1, 2);//s1 = s2[1] + s2[2]
cout << s1 << endl;
//输出:ix
③assign(str)
s1.assign("hello world");//s1 = "hello world"
cout << s1 << endl;
④assign(str, n)
将str的前n个字符赋值给s1
s1.assign("recognize", 5);//s1 = "recog"
cout << s1 << endl;
⑤assign(n, c)
将n个字符c赋值给s1
s1.assign(4, 'c');//s1 = "cccc"
cout << s1 << endl;
5、insert
insert:任意位置插入
①insert(pos, s)
在s1的pos下标处插入s
s1.insert(0, s2);
cout << s1 << endl;
//输出:xixihello world
②insert(pos, s2, n)
在s1的pos下标出插入s的前n个字符
s1.insert(3, s2, 2);
cout << s1 << endl;
//输出:helxilo world
③insert(pos, str)
在pos处插入字符串str
s1.insert(1, "qnmd");
cout << s1 << endl;
//输出:hqumdello world
④insert(pos, str, n)
在pos处插入字符串str的前n个字符
s1.insert(1, "wsnd", 2);
cout << s1 << endl;
//输出:hwsello world
6、erase
erase(pos,len):从pos位置开始删除len个数据,不写len就是全删
s1.erase(1);
cout << s1 << endl;
//输出:h
7、replace
替换
s1.replace(1, 2, s2, 3, 4);
//从左到右数字代表的含义:从s1[1]开始,往后两个字符,替换成s2[3]开始
//往后的四个字符,s2小于4就替换到s2结束,后两个参数可不写
cout << s1 << endl;
//输出:hxixilo world
8、swap
交换
s1.swap(s2);
//s1 = xixi
//s2 = hello world
9、pop_back
s1.pop_back();
cout << s1 << endl;
//输出:hello worl
五、操作
string s("hello world);
1、c_str
c_str:返回string的首元素的指针,保证以\0结尾
string s("hello world");
cout << s.c_str() << endl;//打印元素,不打印地址
2、data
data:和c_str功能差不多,c++11之前不保证\0,之后保证
cout << s.data() << endl;
3、copy
copy:size_t copy(char* s, size_t len,size_t pos = 0) const;
在 C++ 中,std::string 类提供了 copy 成员函数,用于将字符串中的内容复制到一个字符数组中。这个函数不会在复制的内容后自动添加空终止符('\0'),因此需要确保目标缓冲区足够大,并在必要时手动添加 '\0'。
char buff[20];
size_t copied = s.copy(buff, 5, 4);//从s的下标为四的字符开始,赋值五个字符到buff
buff[5] = '\0';
for (int i = 0; i < copied; i++)
{cout << buff[i];
}
4、find
find:size_t find (const string& str, size_t pos = 0)const
返回从pos位置开始找到的c字符或字符串(string)第一次出现的下标位置,没出现返回整形最大值
size_t pos = s.find("ho",3);
cout << pos;
5、rfind
rfind:从后往前找
string b("test.c.zip");
size_t pos1 = b.rfind('.');
for (int i = pos1; i < b.size(); i++)
{cout << b[i];
}
cout << endl;
//输出:.zip
6、find_first_of
find_first_of:可以找到字符串中的的任意一个第一个出现的字符
size_t pos2 = s.find_first_of("abcd");
cout << pos2;
cout << endl;
//输出:10
//hello world中第一个出现的是‘d’,所以pos就是字符d所在位置的下标
7、find_last_of
find_last_of:从后往前找
size_t pos3 = s.find_last_of("hed");
cout << pos3 << endl;
//输出:10
//对应d所在下标
8、substr
string substr (size_t pos = 0, size_t len = npos) const;
提取从pos往后的len个字符
string ss = s.substr(3, 5);
cout << ss << endl;
//输出:lo wo
9、getline
①istream& getline (istream& is, string& str, char delim);
遇到字符delim结束输入,会默认删除原数据
getline(cin, s, 'c');
cout << s;
//输入:abcdefghigk
//输出:ab
②istream& getline (istream& is, string& str);
换行结束
getline(cin, s);
cout << s;
完