[TOC]
# 简介
string封装了`char*`,管理这个字符串,是一个`char*`型的容器
# 常用操作
## string构造函数
~~~
string();//创建一个空的字符串 例如: string str;
string(conststring& str);//使用一个string对象初始化另一个string对象
string(constchar* s);//使用字符串s初始化
string(int n, char c);//使用n个字符c初始化
~~~
~~~
string s1;
string s2(10, 'a');
string s3(s2);
string s4("hello");
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
cout << s4 << endl;
~~~
## 基本赋值操作
~~~
string&operator=(constchar* s);//char*类型字符串 赋值给当前的字符串
string&operator=(conststring&s);//把字符串s赋给当前的字符串
string&operator=(char c);//字符赋值给当前的字符串
string& assign(constchar *s);//把字符串s赋给当前的字符串
string& assign(constchar *s, int n);//把字符串s的前n个字符赋给当前的字符串
string& assign(conststring&s);//把字符串s赋给当前字符串
string& assign(int n, char c);//用n个字符c赋给当前字符串
string& assign(conststring&s, int start, int n);//将s从start开始n个字符赋值给字符串,如s=hello,那么n=3,start=1,那么是hel中从e开始赋值3-1个字符
~~~
~~~
string s1;
s1 = "hello";
cout << s1 << endl;
string s2;
s2.assign("world", 2);
cout << s2 << endl;
~~~
## string存取字符操作
[]和at的区别:[]访问元素时,越界不抛异常,直接挂,at越界,会抛异常
~~~
char&operator[](int n);//通过[]方式取字符
char& at(int n);//通过at方法获取字符
~~~
~~~
string s = "hello world";
for (int i = 0; i < s.size(); ++i) {
cout << s[i] << " ";
}
cout << endl;
for (int j = 0; j < s.size(); ++j) {
cout << s.at(j) << endl;
}
~~~
~~~
//[]和at的区别:[]访问元素时,越界不抛异常,直接挂,at越界,会抛异常
try
{
//cout << s[100] << endl;
cout << s.at(100) << endl;
}
catch (out_of_range &ex)
{
cout << ex.what() << endl;
cout << "at越界" << endl;
}
~~~
## 拼接操作
~~~
string&operator+=(conststring& str);//重载+=操作符
string&operator+=(constchar* str);//重载+=操作符
string&operator+=(constchar c);//重载+=操作符
string& append(constchar *s);//把字符串s连接到当前字符串结尾
string& append(constchar *s, int n);//把字符串s的前n个字符连接到当前字符串结尾
string& append(conststring&s);//同operator+=()
string& append(conststring&s, int pos, int n);//把字符串s中从pos开始的n个字符连接到当前字符串结尾
string& append(int n, char c);//在当前字符串结尾添加n个字符c
~~~
~~~
string s1 = "aaa";
s1 += "bbb";
s1 += 'c';
cout << s1 << endl;
s1.append("ddddddd", 3);
cout << s1 << endl;
~~~
## 查找和替换
~~~
int find(const string& str, int pos = 0) const; //查找str第一次出现位置,从pos开始查找
int find(constchar* s, int pos = 0) const; //查找s第一次出现位置,从pos开始查找
int find(constchar* s, int pos, int n) const; //从pos位置查找s的前n个字符第一次位置
int find(constchar c, int pos = 0) const; //查找字符c第一次出现位置
int rfind(conststring& str, int pos = npos) const;//查找str最后一次位置,从pos开始查找
int rfind(constchar* s, int pos = npos) const;//查找s最后一次出现位置,从pos开始查找
int rfind(constchar* s, int pos, int n) const;//从pos查找s的前n个字符最后一次位置
int rfind(constchar c, int pos = 0) const; //查找字符c最后一次出现位置
string& replace(int pos, int n, const string& str); //替换从pos开始n个字符为字符串str
string& replace(int pos, int n, const char* s); //替换从pos开始的n个字符为字符串s
~~~
~~~
string s = "abcdefgd";
cout << s.find('d') << endl;//3
cout << s.rfind('d') << endl;//7
cout << s.find("kkk") << endl;
s.replace(2, 4, "AAA");
cout << s << endl;
~~~
## 比较操作
~~~
/*
compare函数在>时返回 1,<时返回 -1,==时返回 0。
比较区分大小写,比较时参考字典顺序,排越前面的越小。
大写的A比小写的a小。
*/
int compare(conststring&s) const;//与字符串s比较
int compare(constchar *s) const;//与字符串s比较
~~~
~~~
string s1 = "hello";
string s2 = "hello";
const char* str = "world";
if (s1.compare(s2)==0)
{
cout << "s1==s2" << endl;
}
~~~
## 子串
~~~
string substr(int pos = 0, int n = npos) const;//返回由pos开始的n个字符组成的字符串
~~~
~~~
string email = "hello world@itcast.com";
int pos = email.find('@');
string username = email.substr(0, pos);
cout << username << endl;
string prex = email.substr(pos + 1);
cout << prex << endl;
~~~
## 插入和删除
~~~
string& insert(int pos, constchar* s); //插入字符串
string& insert(int pos, conststring& str); //插入字符串
string& insert(int pos, int n, char c);//在指定位置插入n个字符c
string& erase(int pos, int n = npos);//删除从Pos开始的n个字符
~~~
~~~
string s = "aaaa";
s.insert(3, "AAA");
cout << s << endl;
s.insert(3, 5, 'M');
cout << s << endl;
s.erase(2, 3);
cout << s << endl;
~~~
## string和c-style字符串转换
~~~
const char *str = "hello";
string s=string(str);
cout << s << endl;
const char *str2=s.c_str();
cout << str2 << endl;
~~~
在c++中存在一个从const char\*到string的隐式类型转换,却不存在从一个string对象到C\_string的自动类型转换。对于string类型的字符串,可以通过c\_str()函数返回string对象对应的C\_string.
通常,程序员在整个程序中应坚持使用string类对象,直到必须将内容转化为char\*时才将其转换为C\_string.
## 迭代器
~~~
string s = "hello";
for (string::iterator it = s.begin(); it != s.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
//反向遍历
for (string::reverse_iterator it = s.rbegin(); it != s.rend(); ++it)
{
cout << *it << " ";
}
cout << endl;
~~~
## 注意
为了修改string字符串的内容,下标操作符\[\]和at都会返回字符的引用。但当字符串的内存被重新分配之后,可能发生错误.
原空间被释放,但是a还是被释放的s[2]空间的别名,如果操作非法的空间,会出错
~~~
string s = "abcde";
char &a = s[2];
char &b = s[3];
a = '1';
b = '2';
cout << "a:" << a << endl;
cout << "b:" << b << endl;
cout << s << endl;
cout << "字符串的原空间地址:" << (int*)s.c_str() << endl;
s = "fdasfdasfdsafdasherewrkewhsaferew";
cout << "字符串的空间地址:" << (int*)s.c_str() << endl;
~~~
- c语言
- 基础知识
- 变量和常量
- 宏定义和预处理
- 随机数
- register变量
- errno全局变量
- 静态变量
- 类型
- 数组
- 类型转换
- vs中c4996错误
- 数据类型和长度
- 二进制数,八进制数和十六进制数
- 位域
- typedef定义类型
- 函数和编译
- 函数调用惯例
- 函数进栈和出栈
- 函数
- 编译
- sizeof
- main函数接收参数
- 宏函数
- 目标文件和可执行文件有什么
- 强符号和弱符号
- 什么是链接
- 符号
- 强引用和弱引用
- 字符串处理函数
- sscanf
- 查找子字符串
- 字符串指针
- qt
- MFC
- 指针
- 简介
- 指针详解
- 案例
- 指针数组
- 偏移量
- 间接赋值
- 易错点
- 二级指针
- 结构体指针
- 字节对齐
- 函数指针
- 指针例子
- main接收用户输入
- 内存布局
- 内存分区
- 空间开辟和释放
- 堆空间操作字符串
- 内存处理函数
- 内存分页
- 内存模型
- 栈
- 栈溢出攻击
- 内存泄露
- 大小端存储法
- 寄存器
- 结构体
- 共用体
- 枚举
- 文件操作
- 文件到底是什么
- 文件打开和关闭
- 文件的顺序读写
- 文件的随机读写
- 文件复制
- FILE和缓冲区
- 文件大小
- 插入,删除,更改文件内容
- typeid
- 内部链接和外部链接
- 动态库
- 调试器
- 调试的概念
- vs调试
- 多文件编程
- extern关键字
- 头文件规范
- 标准库以及标准头文件
- 头文件只包含一次
- static
- 多线程
- 简介
- 创建线程threads.h
- 创建线程pthread
- gdb
- 简介
- mac使用gdb
- setjump和longjump
- 零拷贝
- gc
- 调试器原理
- c++
- c++简介
- c++对c的扩展
- ::作用域运算符
- 名字控制
- cpp对c的增强
- const
- 变量定义数组
- 尽量以const替换#define
- 引用
- 内联函数
- 函数默认参数
- 函数占位参数
- 函数重载
- extern "C"
- 类和对象
- 类封装
- 构造和析构
- 深浅拷贝
- explicit关键字
- 动态对象创建
- 静态成员
- 对象模型
- this
- 友元
- 单例
- 继承
- 多态
- 运算符重载
- 赋值重载
- 指针运算符(*,->)重载
- 前置和后置++
- 左移<<运算符重载
- 函数调用符重载
- 总结
- bool重载
- 模板
- 简介
- 普通函数和模板函数调用
- 模板的局限性
- 类模板
- 复数的模板类
- 类模板作为参数
- 类模板继承
- 类模板类内和类外实现
- 类模板和友元函数
- 类模板实现数组
- 类型转换
- 异常
- 异常基本语法
- 异常的接口声明
- 异常的栈解旋
- 异常的多态
- 标准异常库
- 自定义异常
- io
- 流的概念和类库结构
- 标准io流
- 标准输入流
- 标准输出流
- 文件读写
- STL
- 简介
- string容器
- vector容器
- deque容器
- stack容器
- queue容器
- list容器
- set/multiset容器
- map/multimap容器
- pair对组
- 深浅拷贝问题
- 使用时机
- 常用算法
- 函数对象
- 谓词
- 内建函数对象
- 函数对象适配器
- 空间适配器
- 常用遍历算法
- 查找算法
- 排序算法
- 拷贝和替换算法
- 算术生成算法
- 集合算法
- gcc
- GDB
- makefile
- visualstudio
- VisualAssistX
- 各种插件
- utf8编码
- 制作安装项目
- 编译模式
- 内存对齐
- 快捷键
- 自动补全
- 查看c++类内存布局
- FFmpeg
- ffmpeg架构
- 命令的基本格式
- 分解与复用
- 处理原始数据
- 录屏和音
- 滤镜
- 水印
- 音视频的拼接与裁剪
- 视频图片转换
- 直播
- ffplay
- 常见问题
- 多媒体文件处理
- ffmpeg代码结构
- 日志系统
- 处理流数据
- linux
- 系统调用
- 常用IO函数
- 文件操作函数
- 文件描述符复制
- 目录相关操作
- 时间相关函数
- 进程
- valgrind
- 进程通信
- 信号
- 信号产生函数
- 信号集
- 信号捕捉
- SIGCHLD信号
- 不可重入函数和可重入函数
- 进程组
- 会话
- 守护进程
- 线程
- 线程属性
- 互斥锁
- 读写锁
- 条件变量
- 信号量
- 网络
- 分层模型
- 协议格式
- TCP协议
- socket
- socket概念
- 网络字节序
- ip地址转换函数
- sockaddr数据结构
- 网络套接字函数
- socket模型创建流程图
- socket函数
- bind函数
- listen函数
- accept函数
- connect函数
- C/S模型-TCP
- 出错处理封装函数
- 多进程并发服务器
- 多线程并发服务器
- 多路I/O复用服务器
- select
- poll
- epoll
- epoll事件
- epoll例子
- epoll反应堆思想
- udp
- socket IPC(本地套接字domain)
- 其他常用函数
- libevent
- libevent简介