string:是表示字符串序列的类,不能操作多字节或者变长字符序列
在使用string类时,必须包含#include头文件以及using namespace std;
常见的接口整理
函数名称 | 功能说明 |
---|---|
string() | 调用默认构造函数,构造一个空串 |
string(const char *s) | 用C_string构造string类对象 |
string(size_t n,char c) | 用n个字符c构造string类对象 |
string(const string& s) | 拷贝构造函数 |
string s1;
string s2("hello world");
string s3(5, 'c');
string s4(s1);
接口名 | 功能说明 |
---|---|
size | 返回有效字符的个数 |
length | 返回有效字符的个数,与size效果相同 |
capacity | 返回空间的总大小 |
empty | 判空操作,如果字符串为空串返回true,否则返回false |
clear | 清空字符串 |
reserve | 为字符串预留空间 |
resize | 将有效字符改为n个,其余的用字符c填充,默认字符c为空 |
说明
size()与length()的方法实现原理相同,引入size()就是为了与其他容器的接口保持一致。
clear()只是清除有效字符,不改变底层空间的大小
resize(size_t n)表示将有效空间的大小改为n,多余的空间用0填充,resize(size_t n,char c)也表示将有效的空间大小改为n,多余的空间用字符c填充
reverse(size_t n)表示为string预留空间,不改变有效元素的个数,如果n小于当前的capacity则空间大小不变,如果大于capacity则增加空间大小,不同的编译器增容机制不同,vs增容大小为1.5capacity
string s1("hello world");
cout << s1.size() << endl;
cout << s1.length() << endl;
cout << s1.capacity()<<endl;
s1.resize(13);
cout << s1;
s1.reserve(40);
cout << s1.capacity() << endl;
接口名 | 功能说明 |
---|---|
operator[] | 返回pos位置的字符 |
begin / end | 迭代器,begin获取第一个字符,end获取最后一个字符的下一个位置 |
rbegin / rend | 反向迭代 |
说明
begin,end迭代器,返回的范围为[begin,end)左闭右开,表示end位置的元素取不到
string s1("hello world");
for (size_t i=0; i < s1.size(); ++i)
{
cout << s1[i]<<" ";
}
cout << endl;
auto it = s1.begin();
while (it != s1.end())
{
cout << *it;
it++;
}
接口名 | 功能介绍 |
---|---|
push_back | 尾插 |
append | 追加一个字符串 |
operator+= | 追加字符串 |
c_str | 返回c格式的字符串 |
find+npos | 从npos的位置往后找字符c,返回字符c所在的位置 |
rfind | 从后往前找 |
substr | 截取字符串 |
string类浅拷贝
//浅拷贝代码
class String
{
public:
String(const char* str = "")
{
if (str == nullptr)
{
assert(str);
return;
}
_str = new char[strlen(str) + 1];
strcpy(_str, str);
}
~String()
{
if (_str)
{
delete[] _str;
_str = nullptr;
}
}
private:
char *_str;
};
上面代码没有显示定义string类的拷贝构造函数,所以系统会调用默认的拷贝构造函数,但是默认的拷贝构造函数为浅拷贝,当函数结束时,调用析构函数时,会造成空间释放错误。
class String
{
public:
String(const char* s = "")
{
if(s==nullptr)
{
assert(s);
return;
}
_str = new char[strlen(s) + 1];
strcpy(_str,s);
}
String(String& s)
:_str(new char[strlen(s._str) + 1];
{
strcpy(_str,str);
}
String operator = (const String& s)
{
if(this!=&s)
{
char *temp = new char[strlen(s._str) + 1];
strcpy(temp,s._str);
delete _str;
_str = temp;
}
return *this;
}
private:
char* _str;
}
void test()
{
String s1("hello");
String s2(s1);
String s3 = s1;
}
int main()
{
test();
return 0;
}
class String
{
public:
String()
{}
String(const char* s = "")
{
size_t _capacity = strlen(s);
_str = new char[_capacity+1];
strcpy(_str, s);
}
String(const String& s)
:_str(nullptr)
{
String temp(s._str);
swap(_str,temp._str);
}
String operator = (const String& s)
{
if(this!=&s)
{
String temp(s._str);
swap(_str,temp._str);
}
return *this;
}
~String()
{
if (_str != nullptr)
{
delete[] _str;
_str = nullptr;
}
}
void Swap(String & s)
{
swap(_str, s._str);
}
private:
char *_str;
};
class String
{
public:
typedef char* iterator;
String(const char* s = "")
:_size(0)
,_capacity(0)
,_str(new char[strlen(s) + 1])
{
_size = strlen(s);
_capacity = 15;
strcpy(_str, s);
}
String(const String& s)
{
String temp(s._str);
this->Swap(temp);
}
String operator = (const String& s)
{
if (this != &s)
{
String temp(s._str);
this->Swap(temp);
}
return *this;
}
void Swap(String& s)
{
swap(_str, s._str);
swap(_size, s._size);
swap(_capacity, s._capacity);
}
~String()
{
if (_str)
{
delete[] _str;
_str = nullptr;
}
}
iterator begin()
{
return _str;
}
iterator end()
{
return _str + _size;
}
String& operator += (char c)
{
pushBack(c);
return *this;
}
void Append(char c)
{
pushBack(c);
}
void Clear()
{
_size = 0;
_str[_size] = '\0';
}
const char* C_str()const
{
return _str;
}
size_t size()
{
return _size;
}
size_t capacity()
{
return _capacity;
}
bool Empty()const
{
if (_size > 0)
return false;
else
return true;
}
const char& operator[](size_t index)const
{
assert(index < _size);
return _str[index];
}
bool operator == (const String& s)
{
if (strcmp(_str, s._str) == 0)
return true;
return false;
}
bool operator !=(const String& s)
{
return !operator==(s);
}
bool operator > (const String& s)
{
if (strcmp(_str, s._str) > 0)
return true;
return false;
}
bool operator >= (const String& s)
{
if (strcmp(_str, s._str) >= 0)
return true;
return false;
}
bool operator < (const String& s)
{
if (strcmp(_str, s._str) < 0)
return true;
return false;
}
bool operator <= (const String& s)
{
if (strcmp(_str, s._str) <= 0)
return true;
return false;
}
void pushBack(char c)
{
if (_size == _capacity)
Reverse(2 * _capacity);
_str[_size++] = c;
_str[_size] = '\0';
}
void Resize(size_t Newsize,char c = '\0')
{
if (Newsize > _size)
{
if (Newsize > _capacity)
{
Reverse(Newsize);
}
memset(_str + _size, c, Newsize);
}
_size = Newsize;
_str[_size] = '\0';
}
void Reverse(size_t Newcapacity)
{
if (Newcapacity > _capacity)
{
char* str = new char[Newcapacity + 1];
strcpy(str, _str);
delete[] _str;
_str = str;
_capacity = Newcapacity;
}
}
private:
friend ostream& operator<<(ostream& _cout, String& s);
friend istream& operator >> (istream& _cin, String& s);
char *_str;
int _size;
int _capacity;
};
ostream & operator<<(ostream & _cout, String & s)
{
_cout << s._str;
return _cout;
}
istream& operator >> (istream& _cin, String& s)
{
s._str = new char[256];
_cin >> s._str;
return _cin;
}
void test()
{
String s1("hello");
cout << s1.size();
String s2(s1);
String s3 = s1;
s1 += 't';
cout<<s1.size();
cout << s1;
cout << endl;
auto it = s1.begin();
while (it != s1.end())
{
cout << *it;
it++;
}
s1.pushBack('!');
cout << s1;
}