[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簡介