string类
- string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
- 在使用string类时,必须包含#include头文件以及using namespace std;
string常见接口
string的其中一个缺点是,插入数据,空间不够需要增容,增容是有性能消耗。
常见构造
- string()
- 构造空的string类对象,即空字符串
- string(const char s)*
- 用C-string(c格式的字符串)来构造string类对象
- string(size_t n,char c)
- string类对象中包含n个字符c
- string(const string& s)
- 拷贝构造函数
#include <string>
#include <iostream>
using namespace std;
int main()
{
string s1;//空字符串
string s2("helloworld");
string s3(5, 'c');
string s4(s2);//拷贝构造
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
cout << s4 << endl;
}
容量操作
-
size_type size()
-
返回字符串中现在拥有的字符数,不计算’\0’
-
size_type length()
- 返回字符串的长度和size()返回的数字相同
size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()
-
size_type capacity()
- 返回在重新申请更多的空间前字符串可以容纳的字符数
一般是按照1.5倍增容,返回的总空间大小不包括‘\0’所占空间
-
bool empty()
- 如果字符串为空则empty()返回真(true),否则返回假(false).
-
clear
- 清空有效字符
clear()只是将string中有效字符清空,不改变底层空间大小
-
void reserve(size_type n=0)
- 为字符串预留空间,知道最多需要多少空间的情况下,可以省区增容的开销
-
为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。
-
resize
- 将有效字符的个数改成n个,多出的空间用字符c填充
resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
#include <string>
#include <iostream>
using namespace std;
int main()
{
string s1("hello world");
string s2("");
//size()
cout << s1.size() << endl;//11
cout << s2.size() << endl;//0
//length()
cout << s1.length() << endl;//11
cout << s2.length() << endl;//0
//capacity()
cout << s1.capacity() << endl;//15
cout << s2.capacity() << endl;//15
//reserve()
s2.reserve(100);
cout << s2.capacity() << endl;//111
//resize()
s1.resize(20, 'x');
for (auto s1 : s1)
{
cout << s1;//hello worldxxxxxxxxx
}
cout << endl;
s1.resize(5);
for (auto s1 : s1)
{
cout << s1;//hello
}
//clear()清空
s1.clear();
cout << s1 << endl;
return 0;
}
访问遍历
- operator[ ]
- 返回pos位置的字符,const string类对象调用
- begin+ end
- begin获取第一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
- rbegin + rend
- rbegin获取指向字符串的最后一个字符的反向迭代器 + rend获取指向字符串的第一个字符之前的理论元素
- 范围for
- C++11支持更简洁的范围for的新遍历方式
#include <string>
#include <iostream>
using namespace std;
int main()
{
//转换成整形
string s("12345");
int value = 0;
//1、size+[]
for (size_t i = 0; i < s.size(); i++)
{
value *= 10;
value += (s[i] - '0');
}
cout << value << endl;
value = 0;
//2、迭代器
string::iterator it = s.begin();
while (it != s.end())
{
value *= 10;
value += (*it - '0');
it++;
}
cout << value << endl;
value = 0;
//反向迭代器
string::reverse_iterator rit = s.rbegin();
while (rit != s.rend())
{
value *= 10;
value += (*rit - '0');
rit++;
}
cout << value << endl;
//范围for(C++11)
for (auto ch : s)
{
cout << ch;
}
}
修改操作
- push_back
- 在字符串后尾插字符c
- append
- 在字符串后追加一个字符串
- operator+=
- 在字符串后追加字符或字符串
- c_str
- 返回C格式字符串
- find + npos
- 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
- rfind
- 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
- substr
- 在str中从pos位置开始,截取n个字符,然后将其返回
- insert
- 在pos位置插入字符或字符串
- erase
- 清除字符或字符串
#include <string>
#include <iostream>
using namespace std;
int main()
{
string s("hello world");
//push_back 尾插字符
s.push_back('!');
cout << s << endl;//hello world!
//append 尾插字符串
s.append("C++");
cout << s << endl;//hello world!C++
//operator+=
string s1("hello");
string s2("world");
s1 += ' ';
s1 += s2;
cout << s1 << endl;//hello world
//c_str
cout << s1.c_str() << endl;//hello world
//find
size_t pos = s1.find(' ');
cout << pos << endl;//5
//rfind
size_t rpos = s1.rfind(' ');
cout << rpos << endl;//5
//substr 从pos位置开始阶段
cout << s1.substr(pos) << endl;// world
//insert
cout << s1.insert(pos, " C++") << endl;//hello C++ world
//erase 清除
s1.erase(pos, 4);
cout << s1 << endl;//hello world
return 0;
}
string模拟实现
namespace mystring
{
class string
{
public:
//构造函数,全缺省
string(char* str = "")
:_str(new char[strlen(str) + 1])
{
strcpy(_str, str);
}
//析构函数
~string()
{
delete[] _str;
_str = nullptr;
}
//拷贝构造函数,深拷贝
string(const string& s)
:_str(new char[strlen(s._str)+1])
{
strcpy(_str, s._str);
}
//size()
size_t size()
{
return strlen(_str);
}
//operator= 赋值运算符重载
string& operator=(const string& s)
{
//防止自己给自己赋值
if (this != &s)
{
//开辟同样大小的空间
char* tmp = new char[strlen(s._str) + 1];
//将内容拷贝过去
strcpy(tmp, s._str);
//释放原来的空间
delete[] _str;
//将新的内容赋值过去
_str = tmp;
}
return *this;
}
//operator[] 运算符重载
char& operator[](size_t i)
{
return _str[i];
}
//c_str()
const char* c_str()
{
return _str;
}
private:
//指针
char* _str;
};
}

1085

被折叠的 条评论
为什么被折叠?



