查询这些接口的网址:点击蓝色字体即可进入请点击
begin返回字符串第一个字符的迭代器
end返回一个迭代器,该迭代器为字符串最后一个字符的后一个。 通常用
begin和end形成一个区间来遍历一个字符串。
cpp string s("ml is cool");
for (std::string::iterator it = s.begin(); it != s.end(); ++it)
cout << *it;
cout << endl;
size返回字符串的长度。

cpp string s("ml is cool");
cout << s.size() << endl;输出的结果为10
capacity
获取储存字符串的容量。
cpp string a("ml is cool");
cout << a.capacity() << endl;输出的结果为15。
npos公共的静态的全局成员。

resize
改变字符串的大小到n,如果n小于size,删除n后面的字符,即在n号位置的字符变成\0,容量不变。如果大于size,
容量改变,比原来字符串多的字符都变成c,如果没有指定给的字符,就用\0进行填充。
cpp string a("ml is cool");
string b("ml is cool");
string c("ml is cool");
a.resize(3);
b.resize(20);
c.resize(20,'h');
reserve
改变容量成n,如果n小于容量(capacity),这是不被允许的。如果n大于capacity,就把容量扩大到n。
empty
判断字符串是否为空。
find
查找字符或者字符串所在的位置,查找到就返回它们的第一次出现的位置,否则返回npos
nops为-1,-1给size_t的时候会变成一个非常大的值。(整型提升)

rfind
从字符串pos位置的字符开始向前进行查找,当pos的值为npos或者为size_t()-1 时就是对整个字符串进行查找。第(3)个是从[pos,pos+n)进行查找。
cpp string str("ml is cool");
cout << str.find("is") << endl;
cout << str.rfind('i',5) << endl;
find_first_of
和find差不多,只不过它是从字符串的pos位置开始向后查找,只要发现和str中的任意一个字符相同,则就返回该字符的位置。
cpp string s("ml is cool");
cout << s.find_first_of("abc", 1) << endl;输出的结果为6。
substr
生成新的string对象,子串是从pos的位置向后获取len个字符,即[pos,pos+len),len的类型为无符号的整型size_t,所以当值很大的时候,是到字符串的结尾。当然负数转为size_t的时候也会变的很大。
cpp string s("ml is cool");
string str;
str = s.substr(0,2);
cout << str << endl;
insert
该接口为插入一段字符。14,都是从
pos位置开始插入一个字符或者字符串。57,对于迭代器iterator的参数,需要传迭代器参数。
erase
从某个位置开始删除,删除len个字符,对于第2个函数,删除迭代器的位置的字符,第三个函数,表示从迭代器的开始位置删到结束位置。
cpp string str("ml is cool");
cout << str << endl;
str.erase(3, 2);
cout << str << endl;
push_back
在字符串的尾部插入一个字符。
cpp string a("ml is cool");
a.push_back('s');
cout << a << endl;输出结果:ml is cools
append
把字符串追加到原来字符串的结尾。当然不同的函数重载有不同的,追加方式。可以说这个函数不用都可以,毕竟有+=,push_back。
cpp string a("ml is cool");
string b("nbnbnbnb");
a.append("hhhhhhhhhh");
cout << a << endl;
a.append("###########", 3);
cout << a << endl;
a.append(3,'h');
cout << a << endl;
a.append(b);
cout << a << endl;
operator+
实现两个字符串的拼接。把后一个字符串连接到前一个字符串上。
cpp string s1("ml ");
string s2("is cool");
string s3;
s3 = s1 + s2;
cout << s3 << endl;
operator+=
+=运算的重载本质就是在原来字符串的后面加上一组新串,或者字符。
cpp string a("ml");
string b(" cool");
a += ' ';
cout << a << endl;
a += "is";
cout << a << endl;
a += b;
cout << a << endl;看结果:

c_str
把string类型的字符串,转换成c语言类型的字符串(就是以\0)
cpp string a("ml is cool");
a += '\0';
a += "hhhhhhhhh";
cout << a.c_str() << endl;clear
清空字符串,字符串长度为0,但容量不变,即不是否开辟的空间。
cpp string a("ml is cool");
a.clear();
下面函数不是string类里面的。
getline如何获取一行字符串呢?仅仅靠
cin,是不行的。这里提供一个函数getline,它不是在string这个类里面的函数,而是std标准库里面的。 下面看它的使用:

对于(1),第一个参数为输入流(cin从键盘上输入),第二个参数为string对象,而第三个参数为以什么结束的字符。
当没有第三个参数的时候,结束以\n为结束的。
cpp string str;
getline(cin, str);
cout << str << endl;
对于一个
string类的实现,它的成员变量主要有:字符的指针,字符串的实际的大小,开辟该字符的容量。
cppchar* _str;
size_t _size;//字符的实际大小
size_t _capacity;//容量构造函数 对于一个字符串我们怎么初始化呢? 要分为几种情况: 1.用户没有传入任何字符 2.用户传入字符串
为了解决上述的情况,我们可以提供全缺省的构造函数。 缺省参数为
"",空字符串,里面只包含\0。_size大小为传入参数字符串的长度_capacity的大小就是_size的大小,当然,也可以开一定的空间。_str开的空间要比_size要大一个,因为要储存\0。
cpp string(const char* str = "")
{
_size = strlen(str);
_str = new char[_size + 1];
_capacity = _size;
strcpy(_str, str);
}拷贝构造 注意要深拷贝,不能直接把
str._str的地址给_str,如果这样会使析构两次,非法释放空间。
cpp string(const string& str)
{
_size = str._size;
_capacity = str._capacity;
_str = new char[_size + 1];
strcpy(_str, str._str);
}析构函数 释放开辟的空间,大小和容量归
0。
cpp ~string()
{
delete[] _str;
_str = nullptr;
_size = _capacity = 0;
}赋值运算符重载 主要注意的是,要把原来
_str指向的字符串释放(判断给自己赋值这种情况),然后重新开辟一段空间,然后赋值过去。
cpp string& operator=(const string& str)
{
if (_str == str._str)
return *this;
delete[] _str;
_size = str._size;
_capacity = str._capacity;
_str = new char[_size + 1];
strcpy(_str, str._str);
return *this;
}+=运算符重载 这里实现两种
+=,一种是+=一个字符,另一种是+=字符串 在+=的时候要判断容量(需要有扩容的处理)
cpp string& operator+=(const char ch)
{
if (_size == _capacity)
{
size_t n= _capacity == 0 ? 4 : _capacity * 2;
reserve(n);
}
_str[_size] = ch;
++_size;
_str[_size] = '\0';
return *this;
}
string& operator+=(const char* str)
{
size_t len = strlen(str);
if (_size + len >= _capacity)
{
size_t n = _capacity == 0 ? len : (_size + len) * 2;
reserve(n);
}
strcpy(_str + _size, str);
_size += len;
return *this;
}
npos静态的不可修改的公共成员static const size_t npos = -1;
查看字符串的长度
cpp size_t size()const
{
return _size;
}查看储存字符串的容量
cpp size_t capacity()const
{
return _capacity;
}查看字符串是否为空
cpp bool empty()const
{
return _size;
}清空字符串 只把字符串变成空串,容量不变。
cpp void clear()
{
_size = 0;
_str[_size] = '\0';
}
[]操作符的重载 要判断一下pos的位置是否正确。
cpp char& operator[](size_t pos)
{
assert(pos < _size);
return _str[pos];
}
const char& operator[](size_t pos)const
{
assert(pos < _size);
return _str[pos];
}改变容量的大小 当n小于
_capacity不做处理,当n大于它时扩充容量。注意数据的保存。
cpp void reserve(size_t n)
{
if (n > _capacity)
{
_capacity = n;
char* temp = new char[_capacity+1];
strcpy(temp, _str);
delete[] _str;
_str = temp;
}
}改变字符串的长度
cpp void resize(size_t n, char ch='\0')
{
if (n <= _size)
{
_str[n] = '\0';
_size = n;
}
else
{
reserve(n);
memset(_str + _size, ch, n - _size);
_size = n;
}
}尾插 在字符串的最后插入一个字符。要注意空间的容量是否够用。不够用的话就需要扩容。这里我就复用我之前写的+=运算符的重载。(还是偷懒舒服)
cpp string& push_back(char ch)
{
*this += ch;
return *this;
}append模拟实现 这里只模拟插入一个字符串,我们会发现这不就是
**+=**的实现嘛。
cpp string& append(const char* str)
{
size_t len = strlen(str);
if (_size + len == _capacity)
{
size_t n = _capacity == 0 ? len : (_size + len) * 2;
reserve(n);//该函数已经把_capacity的值扩充到了n
}
strcpy(_str + _size, str);
return *this;
}c_str,转换成c语言样式的字符串,注意只是只读,所以用const。
cpp const char* c_str()const
{
return _str;
}查找 从某个位置开始进行查找字符串或者查找某个字符,返回第一个匹配的位置的下标,对于查找的位置要注意是否合法,当然对于查找字符串的时候,用
strstr查找到的时候会返回匹配的字符串的首个字符的地址。对于它的位置,我们用指针相减即可获得该匹配的位置。
cpp size_t find(char ch, size_t pos)const
{
assert(pos < _size);
for (size_t i = pos; i < _size; ++i)
{
if (_str[i] == ch)
return i;
}
return npos;
}
size_t find(const char* str, size_t pos)const
{
assert(pos < _size);
char* p = strstr(_str+pos, str);
if (p == nullptr)
return npos;
else
{
return p - _str;
}
}任意位置插入字符或者字符串 判断插入的位置是否正确,是否需要扩容。
cpp string& insert(size_t pos, char ch)
{
assert(pos < _size);
if (_size == _capacity)
{
reserve(_capacity + 1);
}
size_t p = _size;
while (p > pos)
{
_str[p] = _str[p - 1];
--p;
}
//strcpy(_str + pos + 1, _str + pos);
_str[pos] = ch;
++_size;
_str[_size] = '\0';
return *this;
}
string& insert(size_t pos, const char* str)
{
assert(pos <= _size);
size_t len = strlen(str);
if (_size + len >= _capacity)
{
size_t newlen = _capacity == 0 ? len : (_size + len) * 2;
reserve(newlen);
}
size_t p = _size;
while (p >= pos)//注意边界问题
{
_str[p + len] = _str[p];
--p;
}
strncpy(_str + pos, str,len);//不能用strcpy因为会拷贝\0。
_size += len;
_str[_size] = '\0';
return *this;
}删除某个位置的字符 首先要判断删除位置是否合法,删除之后要修改
size的大小。删除的时候我们从后往前覆盖。
cpp string& erase(size_t pos = 0, size_t len = npos)
{
assert(pos < _size);
if (len == npos || len >= _size - pos)
{
_size = pos;
_str[_size] = '\0';
return *this;
}
strcpy(_str + pos, _str + len);
return *this;
}首字符,末字符的迭代器
string类的迭代器其实就是指针。
cpp typedef char* iterator;
iterator begin()
{
return _str;
}
iterator end()
{
return _str + _size;
}流插入,流提取重载
cpp ostream& operator<<(ostream& os, const string& str)
{
for (size_t i = 0; i < str.size(); ++i)
{
os << str[i];
}
return os;
}
istream& operator>>(istream& oi, string& str)
{
char ch;
ch = oi.get();
while (ch != ' ' && ch != '\n')
{
str += ch;
ch = oi.get();
}
str += '\0';
return oi;
}这里的流插入用到了
get

该函数是为了获得一个字符。