【C++】零基础学好string类的各种接口这一篇就够了
- string常见构造(初始化)
- 如何遍历string
- iterator迭代器
- begin与end
- rbegin与rend
- Capacity容量操作
- 增
- operator+=(尾插)
- push_back(尾插)
- append(尾插)
- insert(输入位置插入)
- 删
- erase(选择删除)
- pop_back(尾删C++11)
- 查
- find(从前往后查找)
- rfind(从后往前查找)
- 改
- assign(删除自身再替换)
- replace(选择替换)
- 字符串操作
- c_str(获得字符串)
- substr(获得原字符串字串)
- getline(字符串输入)
- swap(字符串交换)
- compare(字符串比较)
- reverse(字符串逆置)
string常见构造(初始化)
在使用string类时,必须包含#include头文件以及using namespace std
- string()(常用)
- string(const char*s)(常用)
- string(const string&s)(常用)
- string(size_t n, char c)
- string (const char*s, size_t n);
- string (const string& str, size_t pos, size_t len = npos);
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1; // 1.构造空的string类对象s1
string s2("hello world"); // 2.用C格式字符串构造string类对象s2
string s3(s2); // 3.拷贝构造s3
string s4(5, 'h'); // 4.string类对象s4中包含n个字符c
string s5("hello world", 5);// 5.s5是从这个字符串头开始复制5个字符过去
string s6(s2, 2, 5); // 6.s6是从s2中下标2开始复制5个字符过去
return 0;
}
能够直接使用cout打印string类,是因为有 流插入<< 和 流提取>> 的运算符重载
如何遍历string
- 通过下标遍历
string类运算符重载过 [ ] 所以可以直接像数组一样使用下标访问
int main()
{
string s("1234");
for (int i = 0; i < 4; i++)
{
cout << s[i] << ' ';
}
}
- 使用范围for遍历
int main()
{
string s("1234");
for (auto& ch : s)
{
cout << ch << ' ';
}
}
- 使用迭代器遍历
迭代器iterator的工作原理行为上类似指针,底层可能是由指针实现的,但不能说他就是指针
int main()
{
string s("1234");
string::iterator it = s.begin();
while (it != s.end())
{
cout << *it << ' ';
it++;
}
}
迭代器遍历的方法是一种通用的方法,在string vector list map等等里面只要支持迭代器,就可以使用迭代器遍历
iterator迭代器
Iterators | 功能 |
---|---|
begin | 正向初始迭代器(有const形式) |
end | 正向结尾迭代器(有const形式) |
rbegin | 反向初始迭代器(有const形式) |
rend | 反向结尾迭代器(有const形式) |
cbegin(C++11) | C++11的const正向初始迭代器 |
cend (C++11) | C++11的const正向结尾迭代器 |
crbegin(C++11) | C++11的const反向初始迭代器 |
crend(C++11) | C++11的const反向结尾迭代器 |
begin与end
- 普通形式(可读可写)
int main()
{
string s("1234");
string::iterator it = s.begin();
while (it != s.end())
{
cout << *it << ' ';
it++;
}
}
- const形式(可读不可写)
int main()
{
string s("1234");
string::const_iterator it = s.begin();
while (it != s.end())
{
cout << *it << ' ';
it++;
}
}
rbegin与rend
反向迭代器,就是从结尾开始,结尾是rbegin,向前遍历,头位置是rend
- 普通形式(可读可写)
int main()
{
string s("1234");
string::reverse_iterator it = s.rbegin();
while (it != s.rend())
{
cout << *it << ' ';
it++;
}
}
- const形式(可读不可写)
int main()
{
string s("1234");
string::const_reverse_iterator it = s.rbegin();
while (it != s.rend())
{
cout << *it << ' ';
it++;
}
}
C++11支持的cbegin cend crbegin crend使用方法差不多,它们就是const版本的只能读不能写,只有一个版本
Capacity容量操作
函数名 | 功能 |
---|---|
size | 返回字符串有效字符长度 |
length | 返回字符串有效字符长度 |
capacity | 返回开辟的空间大小 |
max_size | 返回字符串的最大大小(固定值一般是2^32) |
empty | 判断字符串是否为空串,是返回true,否则返回false |
clear | 清空有效字符(不会改变capacity的大小) |
reserve | 为字符串预留空间,更改容量大小 |
resize | 改变字符串大小(长度) |
shrink_to_fit(C++11) | 请求字符串减小其容量以适应其大小 |
- reserve
- resize
resize有三种情况:-
n<原始长度
-
原始长度<n<capacity
-
n>capacity
-
- shrink_to_fit
它的作用是比如一个字符串开辟了100个字节的空间,但是他可能只需要10个字节存储数据,那么shrink_to_fit的作用就是将容量更改为10个字节,减小原空间的大小去适应需要的空间大小
增
operator+=(尾插)
push_back(尾插)
append(尾插)
通过在当前值的末尾附加额外的字符来扩展字符串
insert(输入位置插入)
在某一位置插入字符或字符串
删
erase(选择删除)
pop_back(尾删C++11)
删除字符串的最后一个字符,有效地将其长度减少1
查
find(从前往后查找)
rfind(从后往前查找)
rfind就是从后向前查找,使用方法与find没啥区别
改
assign(删除自身再替换)
为字符串赋一个新值,替换其当前内容(先删除自己的然后替换成别人的)
replace(选择替换)
用新内容替换字符串中以pos字符开始、跨度为len字符的部分(或在[i1,i2)范围内的部分)
第三个与第一个是类似的,第三个是直接传C字符串,第一个是传对象
字符串操作
c_str(获得字符串)
返回一个指向数组的指针,该数组包含以空结束的字符序列(即C-string),表示字符串对象的当前值
还可以打印文件:
int main()
{
string file("Test.cpp");
FILE* fout = fopen(file.c_str(), "r");
assert(fout);
char ch = fgetc(fout);
while (ch != EOF)
{
cout << ch;
ch = fgetc(fout);
}
fclose(fout);
return 0;
}
substr(获得原字符串字串)
返回一个新构造的字符串对象,其值初始化为该对象的子字符串的副本
思考题:取出文件的后缀名
int main()
{
string s("Test.cpp");
size_t pos = s.rfind('.');
if (pos != string::npos)
{
string suffix = s.substr(pos);
cout << suffix << endl;
}
return 0;
}
getline(字符串输入)
跟cin作用类似,只不过它可以传空格等字符,而cin不行
swap(字符串交换)
交换函数
可以直接交换对象或者单个字符
compare(字符串比较)
字符串比较函数(用的不多)一般直接使用 > < = 等运算符
C++的string类重载了很多比较的操作符,所以可以直接使用别的方法比较比如 [ ]+下标:
reverse(字符串逆置)
这个函数需要引用头文件 #include “algorithm”
寒雒: 谢谢博主,文章很有帮助,内容简洁干练,总结到位.向大佬学习
Fragilenot: 请问博主 C++11有更好的办法是什么
Tina_Run_润: 感谢分享【数据链路层】网络基础 -- MAC帧协议与ARP协议,期待一同进步!
黑夢: 优质好文,内容丰富,结构严谨,感谢大佬的分享,期待大佬持续输出好文
小白在努力jy: 大佬的文章让我对这领域的技术问题有了更深入的了解,尤其是大佬提到的那些“坑点”,我相信能够在实际应用中避免或解决很多问题。谢谢大佬的分享,期待大佬的更多精彩文章,让我们共同学习、进步。