1、类介绍
字符串是表示字符序列的对象。
标准一串类提供对此类对象的支持,接口类似于标准集装箱字节,但添加了专门用于操作单字节字符字符串的功能。
这个一串类是基本字符串使用的类模板char(即字节)作为其_字符类型_,默认值为性格特征和分配器类型(请参见基本字符串有关模板的更多信息)。
注意,这个类独立于所使用的编码来处理字节:如果用于处理多字节或可变长度字符的序列(如UTF-8),则该类的所有成员(例如长度或大小),以及它的迭代器,仍将按字节(而不是实际编码字符)进行操作。
1.1 构造函数
1.1.1 拷贝构造函数
| copy | string (const string& str); |
| substring | string (const string& str, size_t pos, size_t len = npos); |
函数说明:copy:构造的副本结构 substring:拷贝字符串str从pos位置到字符串的尾部
模拟实现:拷贝函数采用的是深拷贝方式因为浅拷贝方式下,两个对象同指一片空间,在一个对象析构时释放空间后另一个对象也在析构时就会发生内存泄漏
string_str(string_str& st1)
:str(new char[strlen(st1.str) + 1])
{
strcpy(this->str, st1.str);
}
string_str(const string_str& st)
:str(nullptr)
{
string_str tem(st.str);
swap(this->str, tem.str);
}
1.1.2 构造函数
| default | string(); |
| from c-string | string (const char* s); |
| from sequence | string (const char* s, size_t n); |
| fill | string (size_t n, char c); |
默认构造函数string() 带参数构造函数:string(const chat*str),
模拟实现:
string_str(const char* _str="")
:_size(strlen(_str)),
str(new char[strlen(_str) + 1]),
_capasity(strlen(_str))
{
strcpy(str, _str);
}
1.1.3 范围构造函数
| range | template string (InputIterator first, InputIterator last); |
1.1.4 代码测试
// string constructor
#include <iostream>
#include <string>
int main ()
{
std::string s0 ("Initial string");
// constructors used in the same order as described above:
std::string s1;
std::string s2 (s0);
std::string s3 (s0, 8, 3);
std::string s4 ("A character sequence");
std::string s5 ("Another character sequence", 12);
std::string s6a (10, 'x');
std::string s6b (10, 42); // 42 is the ASCII code for '*'
std::string s7 (s0.begin(), s0.begin()+7);
std::cout << "s1: " << s1 << "\ns2: " << s2 << "\ns3: " << s3;
std::cout << "\ns4: " << s4 << "\ns5: " << s5 << "\ns6a: " << s6a;
std::cout << "\ns6b: " << s6b << "\ns7: " << s7 << '\n';
return 0;
}
2 常见函数介绍
2.1 Capacity
2.1.1 size函数
返回的是字符串的长度 ,类型为size_t,单位为字节
模拟实现:
size_t size(){
retirn size;
}
2.1.2 resize函数
函数原型
void resize (size_t n); void resize (size_t n, char c);
将字符串大小调整为n个字符的长度。
如果n小于当前字符串长度,则当前值将缩短为其第一个n个字符,删除超过n个字符的字符。
如果n大于当前字符串长度,则通过在末尾插入所需数量的字符来扩展当前内容,以达到n的大小。如果指定了c,则新元素初始化为c的副本,否则,它们是值初始化字符(空字符)。
模拟实现:resize的模拟实现要份3中情况(1)n比size()小直接将'\0'插入到str[n]处就行
(2) n比size()大比capacity() 小从size到n的赋值为ch size更新为n
(3) n比capacity()大首先扩容接着从size到n赋值为ch 更新size为n
void resize(size_t num,char ch='\0') {
if (num <= this->_size) {
this->str[num] = '\0';
this->_size = num;
}
else {
if (num >_capasity) {
reserve(num);
}
for (int i = _size; i < num; i++) {
str[i] = ch;
}
_size = num;
str[num] = '\0';
}
}
size_t size() {
return _size;
}
size_t capacity() {
return _capasity;
}
2.1.3 reserve函数
函数原型:void reserve (size_t n = 0);
函数介绍:
要求调整字符串容量以适应计划中的更改,以适应最新字符。
如果大于currentstring容量,则该函数会使容器增加其CapacityTonCharacters(或更大)。
在所有其他情况下,它被视为收缩字符串容量的非绑定请求:容器实现可以自由地进行其他优化,并使字符串的容量大于n。
此函数对字符串长度没有影响,并且不能更改其内容。开辟底层容量
模拟实现:首先要清楚reserve扩容并不影响有效字符串 首先扩展新空间时原来空间大小的2倍数,接着将旧空间的数据复制到新空间,释放老空间,将老空间指针指向新空间
void reserve(size_t num) {
if (num >= _capasity) {
char* str1 = new char[num + 1];
strcpy( str1,this->str);
delete[] str;
this->str = str1;
_capasity = num;
}
}
2.1.4 clear函数
函数功能:将字符串清空
2.1.5 empty函数
函数功能:字符串的判空
2.2 Iterators迭代器
2.2.1 begin
函数原型:返回指向字符串第一个字符的迭代器。
iterator begin();
const_iterator begin() const;
2.2.2 end
函数原型:理论上返回的是最后一个字符的迭代器,但是最后一个字符不能引用,所以指向最后一个字符后边的迭代器
iterator end();
const_iterator end() const;
2.2.3 rbegin
函数原型:返回的是字符串的最后一个字符的迭代器,也就是字符串的反向的开头
reverse_iterator rbegin(); const_reverse_iterator rbegin() const;
2.2.4 rend
函数原型:返回字符串的第一个字符的前一个迭代器
reverse_iterator rend(); const_reverse_iterator rend() const;
string的迭代器其实就是指针,对迭代器的操作就是对指针的操作对迭代器的++就是将指针所指向的位置向后移动一位 —就是将指针向前移动一位
string迭代器原型:
typedef char* Iterator;
typedef const char* const_Iterator;
typedef char* reserve_Iterator;
typedef char* Iterator;
Iterator begin() {
return str;
}
Iterator end() {
return str + _size;
}
2.3 Modifiers:
2.3.1 operator+=
函数原型:通过在字符串当前值的末尾附加其他字符来扩展字符串:字符串拼接 返回值为拼接后字符串对象
| string (1) | string& operator+= (const string& str); |
| c-string (2) | string& operator+= (const char* s); |
| character (3) | string& operator+= (char c); |
2.3.2 appened
函数原型:
| string (1) | string& append (const string& str); |
| substring (2) | string& append (const string& str, size_t subpos, size_t sublen); |
| c-string (3) | string& append (const char* s); |
| buffer (4) | string& append (const char* s, size_t n); |
| fill (5) | string& append (size_t n, char c); |
| range (6) | template string& append (InputIterator first, InputIterator last); |
模拟实现:将要插入到字符串拷贝到字符串的后边就可以
void append(const char* ch) {
size_t len = strlen(ch);
if (_size + len > _capasity) {
this->reserve(_size + len);
}
strcpy(this->str+_size,ch);
_size += len;
}
}
2.3.3 push_back
函数原型:将字符c追加到字符串的末尾,将其长度增加1。
void push_back (char c);
模拟实现:再插入前都要进行容量判断,容量不够就要扩容
void push_back(char ch) {
if (_size >= _capasity) {
size_t num = _capasity == 0 ? 4 : 2 * _capasity;
this->reserve(num);
}
str[_size] = ch;
_size++;
str[_size] = '\0';
//\0标志字符串结束
}
2.3.4 insert
函数原型:
| string (1) | string& insert (size_t pos, const string& str); |
| substring (2) | string& insert (size_t pos, const string& str, size_t subpos, size_t sublen); |
| c-string (3) | string& insert (size_t pos, const char* s); |
| buffer (4) | string& insert (size_t pos, const char* s, size_t n); |
| fill (5) | string& insert (size_t pos, size_t n, char c); void insert (iterator p, size_t n, char c); |
| single character (6) | iterator insert (iterator p, char c); |
| range (7) | template void insert (iterator p, InputIterator first, InputIterator last); |
void insert(size_t pos, char ch) {
assert(pos >= 0 && pos <= _size);
if (_size >= _capasity) {
size_t num = _capasity == 0 ? 4 : 2 * _capasity;
this->reserve(num);
}
int p = _size-1;
/* for (size_t i = this->_size; i >= pos; i--) {
this->str[i + 1] = this->str[i];
}*/
while (true) {
this->str[p + 1] = this->str[p];
p--;
if (p < (int)pos) {
break;
}
}
this->_size++;
this->str[pos] = ch;
}
void insert(size_t pos,const char* str1) {
assert(pos >= 0 && pos <= _size);
size_t len = strlen(str1);
if (_size + len > _capasity) {
this->reserve(_size + len);
}
int p = _size - 1;
/* for (size_t i = this->_size; i >= pos; i--) {
this->str[i + 1] = this->str[i];
}*/
while (true) {
this->str[p + len] = this->str[p];
p--;
if (p < (int)pos+len) {
break;
}
}
int j = 0;
for (size_t i = pos; i < pos + len; i++) {
str[i] = str1[j++];
}
_size += len;
str[_size] = '\0';
}
2.3.5 erase
函数原型
| sequence (1) | string& erase (size_t pos = 0, size_t len = npos); 删除区间[pos,len]的字符 |
| character (2) | iterator erase (iterator p); |
| range (3) | iterator erase (iterator first, iterator last); |
void erase(size_t pos, int len = -1) {
assert(pos < _size&& pos >= 0);
if (len == -1|| pos + len >= _size) {
str[pos] = '\0';
_size = pos;
}
else {
strcpy(str + pos, str + pos + len);//将后边的字符串拷贝到前边最后在尾端加上’\0‘
int p = _size - len;
str[p] = '\0';
_size -= len;
}
}
ostream& oper
2.3.6 pop_back
函数原型:擦除字符串的最后一个字符,有效地将其长度减少一个。
void pop_back();
2.4 String operations:
2.4.1 c_str函数
函数原型: const char* c_str() const;
返回指向数组的指针,该数组包含表示字符串对象当前值的以null结尾的字符序列(即C字符串)。
此数组包含组成字符串对象值的相同字符序列,并在末尾附加一个终止的空字符(“\0”)。
2.4.2 find函数
函数原型:在字符串中搜索由其参数指定的序列的第一个匹配项。
| string (1) | size_t find (const string& str, size_t pos = 0) const; |
| c-string (2) | size_t find (const char* s, size_t pos = 0) const; |
| buffer (3) | size_t find (const char* s, size_t pos, size_t n) const; |
| character (4) | size_t find (char c, size_t pos = 0) const; |
指定pos时,搜索仅包括pos位置处或之后的字符,忽略任何可能出现的包含pos之前字符的情况。
2.4.3 substr
函数原型:
返回一个新构造的字符串对象,其值初始化为该对象子字符串的副本。
子字符串是对象中从字符位置pos开始并跨越len个字符(或直到字符串末尾,以先到者为准)的部分。
string substr (size_t pos = 0, size_t len = npos) const;
2.4.4 getline
函数原型:字符换的输入
| (1) | istream& getline (istream& is, string& str, char delim); |
| (2) | istream& getline (istream& is, string& str); |
istream& getline( string_str& str, istream& in) {
str.clear();
char ch;
ch = in.get();
while ( ch != '\0') {
str += ch;
ch = in.get();
}
return in;
}
2.4.5 cin and out
在输入字符串时可以直接输入但是在C中char*是不可以直接输入的所以还要实现string的输入输出
输入输出原理就是从stdin中读入字符,然后将字符插入到字符串的后边
ostream& operator<<( string_str& str, ostream&out) {
for (size_t i = 0; i < _size; i++) {
out >> str[i];
}
return out;
}
istream& operator>>(string_str& str, istream& in) {
str[0] = '\0';
_size = 0;
char ch;
ch = in.get();
while (ch != ' ' && ch != '\0'){
str += ch;
ch = in.get();
}
return in;
}