Ⅴ. string 类对象的修改操作
函数名称 | 功能说明 |
push_back | 在字符串后尾插字符c |
append | 在字符后追加一个字符串 |
operator+= (重点) | 在字符串后追加字符串str |
c_str (重点) | 返回c格式字符串 |
0x00 用来插入字符的 push_back()
string 用的最多的可能就是插入了。
📚 push_back:插入一个字符,但只能插入一个字符
int main(void) { string s1("hello, "); s1.push_back('C'); cout << s1 << endl; return 0; }
0x01 用来插入字符串的 append()
📚 append:可以插入字符串,它就能干很多
(关于迭代器部分的知识我下面几章会说)
💬 这里面用的最多的就是 (1) 和 (3) ,插入一个完整字符串和插入一个对象。
int main(void) { string s1("hello, "); s1.append("C++"); cout << s1 << endl; return 0; }
0x02 用起来爽到飞起的 operator+=
📚 还有用起来更舒服的 —— operator+=
int main(void) { string s1("hello, "); s1 += 'C'; // 加个字符 cout << s1 << endl; s1 += ' '; // 加个空格 cout << s1 << endl; s1 += "C++"; // 加字符串 cout << s1 << endl; return 0; }
0x03 返回C格式字符串的 c_str
📚 返回字符串指针
💬 代码演示:
void Test() { string s1("hello string"); cout << s1 << endl; // 调用重载的流插入运算符打印的 cout << s1.c_str() << endl; // 这是调字符串打印的,c_str 是遇到 \0 结束的, }
(结果看起来很像)
❓ 那这个 c_str 有什么意义呢?
// 获取file后缀 void Test() { string file("test.txt"); FILE* pf = fopen(file.c_str(), "w"); }
比如这里需要打开文件,fopen 第一个参数要求是 const char*,
所以这里怎么能直接放 string 是不行的,这时候可以用 .c_str() 就可以把字符串的地址返回出来。
0x04 追查字符位置的 find() 和砍字符串的 substr()
如果我们要取像这样的文件后缀名 .txt 或 .cpp,该怎么取?
使用 find() 就可以很好地解决!
📚 find:从字符串 pos 位置开始往后找字符 c ,返回该字符在字符串中的位置。
string file("test.txt"); FILE* pf = fopen(file.c_str(), "w"); size_t pos = file.find('.'); // 不写第二个参数,默认从0位置开始找。
通过文档,了解它的返回值后,我们就知道如何判断它了。
在这之前我们还要介绍一下可以砍字符串的 substr
📚 substr:在 str 中从 pos 位置开始,截取 n 个字符,然后将其返回。
💬 判断部分:
void Test() { string file("test.txt"); FILE* pf = fopen(file.c_str(), "w"); size_t pos = file.find('.'); // 不写第二个参数,默认从0位置开始找。 if (pos != string::npos) { string suffix = file.substr(pos, file.size() - pos); cout << suffix << endl; } }
用 find 截取到 " . " 存入 pos,pos 的位置就是起始位置,就作为 substr() 的第一个参数 pos,
substr() 的第二个参数 len ,我们可以通过 size() - pos 来算出要截取多少个字符。
其实第二个参数你可以不给,看上面的文档可知,参数二 len 的缺省值是 npos,
并且 len 是 size_t 的,也就是说如果你不写,它默认会是我们所说的 "上亿的大数"
这种数肯定会超出字符串长度。而且要求是获取后缀,
因为考虑到 .txt .cpp 这样的后缀,后面也没东西,这时候就会有多少出多少
💬 所以如果你懒的话甚至可以直接这样写:
void Test() { string file("test.txt"); FILE* pf = fopen(file.c_str(), "w"); size_t pos = file.find('.'); if (pos != string::npos) { string suffix = file.substr(pos); // 给个pos就完事了 cout << suffix << endl; } }
find 是很常用的!也是很重要的!我们还可以拿它取 url :
void Test() { // 创建字符串记录网址 string url("http://www.cplusplus.com/reference/string/string/find/"); // 取出协议 size_t pos1 = url.find(':'); string protocol = url.substr(0, pos1 - 0); cout << protocol << endl; // 取出域名 size_t pos2 = url.find('/', pos1 + 3); // 冒号位置+3开始往后找(w位置) string domain = url.substr(pos1 + 3, pos2 - (pos1 + 3)); cout << domain << endl; // 取出路径 string uri = url.substr(pos2 + 1); cout << uri << endl; }
0x05 反向追查字符串的 rfind()
但是,如果文件后缀名是 .txt.zip 呢?我们要取 .zip 啊。
如果还是按刚才的方式去取,会从第一个 " . " 开始选取·:
void Test() { string file("test.txt.zip"); FILE* pf = fopen(file.c_str(), "w"); size_t pos = file.find('.'); if (pos != string::npos) { string suffix = file.substr(pos, file.size() - pos); cout << suffix << endl; } }
(最后得到的结果不是我们想要的)
这种情况,就需要从右往左去找了。
📚 rfind:从字符串 pos 位置开始往前找字符 c ,返回该字符在字符串中的位置。
rfind,就是 right find —— 从右往左去找字符。
💬 这里我们只需要改成 rfind 就可以了:
void Test() { string file("test.txt.zip"); FILE* pf = fopen(file.c_str(), "w"); size_t pos = file.rfind('.'); if (pos != string::npos) { string suffix = file.substr(pos, file.size() - pos); cout << suffix << endl; } }
Ⅵ. string 类非成员函数
函数 | 功能说明 |
operator+ | 尽量少用,因为传值返回,导致深拷贝效率低 |
operator>> (重点) | 输入运算符重载 |
operator<< (重点) | 输出运算符重载 |
getline (重点) | 获取一行字符串 |
relational operators (重点) | 大小比较 |
string类中还有很多操作,这里就不一一列举了,需要用到时不明白可以查文档。
……
End.