C++:5.STL:string 2

前言
今天就是String的第二节课啦,我们这节课要讲String类的实现,因为比较简单,所以我们以代码为主 (其实主要原因是博主忙着刷题 )。这里主要讲一些常用的String类的方法,博主基本都实现了一下。下面让我们开始吧!首先就是本章的思维导图了!见下图>>

四个默认成员函数
构造函数
cpp
string(const char* s = "")
:_str(new char[strlen(s)+1])
,_size(0)
,_capacity(strlen(s))
{
strcpy(_str, s);
_size = _capacity;
}
析构函数
cpp
~string()
{
delete[] _str;
_str = nullptr;
_capacity = _size = 0;
}
拷贝构造函数
cpp
string(const string& str)
:_str(new char[strlen(str._str)+1])
,_size(0)
,_capacity(strlen(str._str))
{
strcpy(_str, str._str);
_size=_capacity;
}
赋值操作符重载函数
cpp
string& operator=(const string& str)
{
if (str._size > _capacity)
{
size_t newcapacity = str._size * 2;
reserve(newcapacity);
}
strcpy(_str, str._str);
_size = str._size;
return *this;
}
string& operator=(const char* s)
{
size_t size = strlen(s);
if (size > _capacity)
{
size_t newcapacity = size * 2;
reserve(newcapacity);
}
strcpy(_str, s);
_size = size;
return *this;
}
修改器
插入元素
cpp
void push_back(char c)
{
if (_size == _capacity)
{
size_t newcapacity = (_size + 1) * 2;
reserve(newcapacity);
}
_str[_size] = c;
++_size;
_str[_size] = '\0';
}
void append(const char* s)
{
size_t size = strlen(s);
if (_size + size > _capacity)
{
size_t newcapacity = (_size + size) * 2;
reserve(newcapacity);
}
strcpy(_str + _size, s);
_size += size;
}
string& operator+=(char c)
{
push_back(c);
return *this;
}
string& operator+=(const char* s)
{
append(s);
return *this;
}
获取c风格字符串的首元素地址
cpp
const char* c_str()const
{
return _str;
}
清除元素
cpp
void clear()
{
_size = 0;
_str[0] = '\0';
}
交换类对象的值
cpp
void swap(string& str)
{
string tmp = str;
str = *this;
*this = tmp;
}
空间
获取类对象的属性
获取对象元素个数
cpp
size_t size()const
{
return _size;
}
获取对象空间大小
cpp
size_t capacity()const
{
return _capacity;
}
判空
cpp
bool empty()const
{
return _size == 0;
}
修改元素个数
cpp
void resize(size_t n, char c = '\0')
{
if (n > _capacity)
{
size_t newcapacity = n * 2;
reserve(newcapacity);
}
if (n <= _size)
{
_size = n;
}
else
{
for (size_t i = _size; i <= n - 1; ++i)
{
_str[i] = c;
}
}
}
扩容
cpp
void reserve(size_t n)
{
//申请的空间比现有的空间更大才扩容、
if (n > _capacity)
{
char* tmp = new char[n + 1];//实际空间为有效空间+1,因为要放'\0'
strcpy(tmp, _str);
delete[] _str;
_str = tmp;
_capacity = n;
}
}
访问
用 访问
cpp
char& operator[](size_t index)
{
return _str[index];
}
const char& operator[](size_t index)const
{
return _str[index];
}
相关的操作符
比较对象
cpp
//因为oprator<等要调用compare(),所以这里实现一下
size_t compare(const string& str)const
{
size_t size = _size < str._size ? _size : str._size;
for (size_t i = 0; i < size; ++i)
{
if (_str[i] < str._str[i])
{
return -1;
}
else if(_str[i] > str._str[i])
{
return 1;
}
}
//一方比较完,并在该区间内两方所有字符都相等
return _size - str._size;
}
大于
cpp
bool operator>(const string& str)
{
return compare(str) > 0;
}
等于
cpp
bool operator==(const string& str)
{
return compare(str) == 0;
}
小于
cpp
bool operator<(const string& str)
{
return compare(str) < 0;
}
大于或等于
cpp
bool operator>=(const string& str)
{
return compare(str) >= 0;
}
小于或等于
cpp
bool operator<=(const string& str)
{
return compare(str) <= 0;
}
不等于
cpp
bool operator!=(const string& str)
{
return compare(str) != 0;
}
其他方法
查找元素
cpp
// 返回c在string中第一次出现的位置
size_t find(char c, size_t pos = 0) const
{
for (size_t i = pos; i < _size; ++i)
{
if (_str[i] == c)
{
return i;
}
}
return npos;
}
// 返回子串str在string中第一次出现的位置
size_t find(const char* s, size_t pos = 0) const
{
size_t size = strlen(s);
if (( size> _size-pos) ||(pos>=_size))
{
return npos;
}
size_t index = 0;
size_t previ = 0;
for (size_t i = pos; i < _size; ++i)
{
if (_str[i] != s[index])
{
if (index > 0)
{
i = previ;
}
index = 0;
}
else
{
if (index == 0)
{
previ = i;//记录上一次匹配时i的位置
}
++index;
if (index == size)
{
break;
}
}
}
if (index == size)
{
return previ;
}
else
{
return npos;
}
}
插入元素
cpp
// 在pos位置上插入字符c/字符串str,并返回该字符的位置
string& insert(size_t pos, char c)
{
//pos在_str有效范围内才插入
if (pos < _size)
{
if (_size == _capacity)
{
size_t newcapacity = (_size + 1) * 2;
reserve(newcapacity);
}
//'\0'也要往后移动
for (size_t i = _size; i >= pos; --i)
{
_str[i + 1] = _str[i];
}
_str[pos] = c;
_size += 1;
}
return *this;
}
string& insert(size_t pos, const char* s)
{
//pos在_str有效范围内才插入
if (pos < _size)
{
size_t size = strlen(s);
if (size + _size > _capacity)
{
size_t newcapacity = (size + _size) * 2;
reserve(newcapacity);
}
for (size_t i = _size; i >= pos; --i)
{
_str[i + size] = _str[i];
}
for (size_t i = pos; i < pos + size; ++i)
{
_str[i] = s[i - pos];
}
_size += size;
}
return *this;
}
删除元素
cpp
// 删除pos位置上的元素,并返回该元素的下一个位置
string& erase(size_t pos, size_t len)
{
//pos位置存在才删除元素
if (pos < _size)
{
//保证len合法
if (len > _size - pos)
{
len = _size - pos;
}
for (size_t i = pos+len; i <= _size; ++i)
{
_str[i - len] = _str[i];
}
_size -= len;
}
return *this;
}
流插入操作符重载
cpp
ostream& firdawn::operator<<(ostream& _cout, const firdawn::string& str)
{
firdawn::string::iterator it = str.begin();
while (it != str.end())
{
_cout << *it;
++it;
}
return _cout;
}
流提取操作符重载
cpp
istream& firdawn::operator>>(istream& _cin, firdawn::string& str)
{
str = "";
char c = '\0';
while ((c = _cin.get()) != EOF)
{
if (c == ' ' || c == '\n')
{
break;
}
else
{
str += c;
}
}
return _cin;
}
获取一整行的元素
cpp
void firdawn::getline(istream& _cin, firdawn::string& str)
{
str = "";
char c = '\0';
while ((c = _cin.get()) != EOF)
{
if (c == '\n')
{
break;
}
else
{
str += c;
}
}
}
全部代码
String.h
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<cassert>
using namespace std;
namespace firdawn
{
class string
{
public:
typedef char* iterator;
const static size_t npos;
//四个默认成员函数
string(const char* s = "")
:_str(new char[strlen(s)+1])
,_size(0)
,_capacity(strlen(s))
{
strcpy(_str, s);
_size = _capacity;
}
string(const string& str)
:_str(new char[strlen(str._str)+1])
,_size(0)
,_capacity(strlen(str._str))
{
strcpy(_str, str._str);
_size=_capacity;
}
string& operator=(const string& str)
{
if (str._size > _capacity)
{
size_t newcapacity = str._size * 2;
reserve(newcapacity);
}
strcpy(_str, str._str);
_size = str._size;
return *this;
}
string& operator=(const char* s)
{
size_t size = strlen(s);
if (size > _capacity)
{
size_t newcapacity = size * 2;
reserve(newcapacity);
}
strcpy(_str, s);
_size = size;
return *this;
}
~string()
{
delete[] _str;
_str = nullptr;
_capacity = _size = 0;
}
//////////////////////////////////////////////////////////////
// iterator
const iterator begin()const
{
return _str;
}
const iterator end()const
{
return _str + _size;
}
/////////////////////////////////////////////////////////////
// modify
void push_back(char c)
{
if (_size == _capacity)
{
size_t newcapacity = (_size + 1) * 2;
reserve(newcapacity);
}
_str[_size] = c;
++_size;
_str[_size] = '\0';
}
void append(const char* s)
{
size_t size = strlen(s);
if (_size + size > _capacity)
{
size_t newcapacity = (_size + size) * 2;
reserve(newcapacity);
}
strcpy(_str + _size, s);
_size += size;
}
string& operator+=(char c)
{
push_back(c);
return *this;
}
string& operator+=(const char* s)
{
append(s);
return *this;
}
void clear()
{
_size = 0;
_str[0] = '\0';
}
void swap(string& str)
{
string tmp = str;
str = *this;
*this = tmp;
}
const char* c_str()const
{
return _str;
}
/////////////////////////////////////////////////////////////
// capacity
size_t size()const
{
return _size;
}
size_t capacity()const
{
return _capacity;
}
bool empty()const
{
return _size == 0;
}
void resize(size_t n, char c = '\0')
{
if (n > _capacity)
{
size_t newcapacity = n * 2;
reserve(newcapacity);
}
if (n <= _size)
{
_size = n;
}
else
{
for (size_t i = _size; i <= n - 1; ++i)
{
_str[i] = c;
}
}
}
void reserve(size_t n)
{
//申请的空间比现有的空间更大才扩容、
if (n > _capacity)
{
char* tmp = new char[n + 1];//实际空间为有效空间+1,因为要放'\0'
strcpy(tmp, _str);
delete[] _str;
_str = tmp;
_capacity = n;
}
}
/////////////////////////////////////////////////////////////
// access
char& operator[](size_t index)
{
return _str[index];
}
const char& operator[](size_t index)const
{
return _str[index];
}
/////////////////////////////////////////////////////////////
//relational operators
//因为oprator<等要调用compare(),所以这里实现一下
size_t compare(const string& str)const
{
size_t size = _size < str._size ? _size : str._size;
for (size_t i = 0; i < size; ++i)
{
if (_str[i] < str._str[i])
{
return -1;
}
else if(_str[i] > str._str[i])
{
return 1;
}
}
//一方比较完,并在该区间内两方所有字符都相等
return _size - str._size;
}
bool operator<(const string& str)
{
return compare(str) < 0;
}
bool operator<=(const string& str)
{
return compare(str) <= 0;
}
bool operator>(const string& str)
{
return compare(str) > 0;
}
bool operator>=(const string& str)
{
return compare(str) >= 0;
}
bool operator==(const string& str)
{
return compare(str) == 0;
}
bool operator!=(const string& str)
{
return compare(str) != 0;
}
// 返回c在string中第一次出现的位置
size_t find(char c, size_t pos = 0) const
{
for (size_t i = pos; i < _size; ++i)
{
if (_str[i] == c)
{
return i;
}
}
return npos;
}
// 返回子串str在string中第一次出现的位置
size_t find(const char* s, size_t pos = 0) const
{
size_t size = strlen(s);
if (( size> _size-pos) ||(pos>=_size))
{
return npos;
}
size_t index = 0;
size_t previ = 0;
for (size_t i = pos; i < _size; ++i)
{
if (_str[i] != s[index])
{
if (index > 0)
{
i = previ;
}
index = 0;
}
else
{
if (index == 0)
{
previ = i;//记录上一次匹配时i的位置
}
++index;
if (index == size)
{
break;
}
}
}
if (index == size)
{
return previ;
}
else
{
return npos;
}
}
// 在pos位置上插入字符c/字符串str,并返回该字符的位置
string& insert(size_t pos, char c)
{
//pos在_str有效范围内才插入
if (pos < _size)
{
if (_size == _capacity)
{
size_t newcapacity = (_size + 1) * 2;
reserve(newcapacity);
}
//'\0'也要往后移动
for (size_t i = _size; i >= pos; --i)
{
_str[i + 1] = _str[i];
}
_str[pos] = c;
_size += 1;
}
return *this;
}
string& insert(size_t pos, const char* s)
{
//pos在_str有效范围内才插入
if (pos < _size)
{
size_t size = strlen(s);
if (size + _size > _capacity)
{
size_t newcapacity = (size + _size) * 2;
reserve(newcapacity);
}
for (size_t i = _size; i >= pos; --i)
{
_str[i + size] = _str[i];
}
for (size_t i = pos; i < pos + size; ++i)
{
_str[i] = s[i - pos];
}
_size += size;
}
return *this;
}
// 删除pos位置上的元素,并返回该元素的下一个位置
string& erase(size_t pos, size_t len)
{
//pos位置存在才删除元素
if (pos < _size)
{
//保证len合法
if (len > _size - pos)
{
len = _size - pos;
}
for (size_t i = pos+len; i <= _size; ++i)
{
_str[i - len] = _str[i];
}
_size -= len;
}
return *this;
}
private:
char* _str;
size_t _size;//有效元素个数
size_t _capacity;//能够存放的有效元素个数
};
ostream& operator<<(ostream& _cout, const string& str);
istream& operator>>(istream& _cin, string& str);
void getline(istream& _cin, firdawn::string& str);
}
String.cpp
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include "String.h"
const size_t firdawn::string::npos = -1;
ostream& firdawn::operator<<(ostream& _cout, const firdawn::string& str)
{
firdawn::string::iterator it = str.begin();
while (it != str.end())
{
_cout << *it;
++it;
}
return _cout;
}
istream& firdawn::operator>>(istream& _cin, firdawn::string& str)
{
str = "";
char c = '\0';
while ((c = _cin.get()) != EOF)
{
if (c == ' ' || c == '\n')
{
break;
}
else
{
str += c;
}
}
return _cin;
}
void firdawn::getline(istream& _cin, firdawn::string& str)
{
str = "";
char c = '\0';
while ((c = _cin.get()) != EOF)
{
if (c == '\n')
{
break;
}
else
{
str += c;
}
}
}
Test.cpp
cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include"String.h"
void TestString1()
{
firdawn::string str;
firdawn::string str2("Time and Tide wait for no man");
firdawn::string str3 = str2;
firdawn::string str4;
str4 = str2;
str.resize(10);
size_t find= str3.find("and ");
cout << str2 << endl;
cout << str3.c_str() << endl;
for (size_t i = 0; i < str4.size(); ++i)
{
cout << str4[i] << " ";
}
cout << endl;
str = str2;
for (auto c : str)
{
cout << c << " ";
}
cout << endl;
str.clear();
cout << str << endl;
/*str = str2;
str += "Trust youself";
cout << str << endl;
cin >> str;
cout << str << endl;
firdawn::getline(cin, str);
cout << str << endl;*/
str = str2;
str.insert(find, "and girl ");
cout << str << endl;
str.erase(find, strlen("and girl "));
cout << str << endl;
str.erase(find, strlen("and tide "));
cout << str << endl;
cout << str << endl;
cout << str2 << endl;
bool less = str > str2;
bool lessOrEqual = str != str2;
cout << less << endl;
cout << lessOrEqual << endl;
str.insert(find, "and tide");
cout << str << endl;
}
int main()
{
TestString1();
return 0;
}
