目录
1.string容器
2.构造函数和析构函数的相关操作
3.迭代器
3.容量相关
4.元素访问相关
5.元素遍历相关
6.字符串操作
6.1 operator+=
6.2 append
6.3 push_back
6.4 insert && erase
6.5swap
7.string模拟实现
1.string容器
string容器是C++标准模板库提供的专门用来存储操作字符串的容器。下边介绍了string容器的一些基本操作,均参考于C++官方文档。
2.构造函数和析构函数的相关操作
#include
#include
using namespace std;
int main() {
const char* arr = "world";
string s0("hello");
string s1(s0);
string s2(s0,0,2);
string s3(10,'a');
string s4(arr, 3);
string s5(s0.begin(), s0.begin() + 3);
~string();
return 0;
}
3.迭代器
begin() 和end()
begin()和end()目前可以看成两个指针,begin()指向字符串的头部,end()指向字符串尾部的下一个位置,即 的位置。我们可以使用begin()和end()进行遍历操作和获取位置操作。
rbegin(),rend()
rbegin()和rend()正好与上边的begin() 和end()相反,rbegin()指向字符串的尾部,即 的位置,rbegin()指向字符串头部。
#include
#include
using namespace std;
int main() {
string s0("hello world!");
string s1(s0.begin(), s0.end());
string s2(s0.rbegin(), s0.rend());
return 0;
}
3.容量相关
size:字符串中有效元素的个数,不包括
capcity:字符串底层顺序表的空间的大小
size_t size() const;
此方法可以求字符串的长度,和C语言中length()方法相似
size_t capacity() const;
此方法可以查看顺序表实际上内部容量,因为string是可以自己扩容的,所以他的容量一定比存储的字符串多,当拷贝的字符串大于capacity时,String底层动态扩容。
void resize (size_t n); void resize (size_t n, char c);
此函数作用是更新有效元素个数,当nsize && ncapcity,则编译器会先申请一块大于n的空间,然后将原来字符串拷贝进去,使用参数c填充,再销毁原空间。
void reserve (size_t n );
此方法可以调整顺序表的容量大小,不会修改有效元素个数,此函数作用是将字符串容量变为n个,当n大于capcity时正常扩容; 当n小于原来capcity且大于有效元素个数时(size),则缩减capcity; 当n小于有效元素个数时,编译器忽略这条指令。
void clear();
清空有效元素,但是不改变capcity大小
bool empty() const;
检测这个字符串是否为空,空则返回true,非空则返回false;
4.元素访问相关
operator[]
char& operator[] (size_t pos); const char& operator[] (size_t pos) const;
string底层就是一个字符数组,所以可以像访问数组一样使用[]访问字符串。
at
char& at (size_t pos); const char& at (size_t pos) const;
at和[]在使用效果方面完全一致,使用方法举例 cout << str.at(i);
区别:[]在越界访问时会触发assert断言,at会抛出异常,可供用户捕获。
5.元素遍历相关
1.for循环
2.范围for
3.迭代器
#include
#include
using namespace std;
int main() {
string s0("hello world!");
//for循环
for (int i = 0; i < s0.size(); i++) {
cout << s0[i];
}
cout << endl;
//范围for
for (auto e : s0) {
cout << e;
}
cout << endl;
//迭代器
string::iterator it = s0.begin();
while (it !=s0.end()) {
cout << *it;
it++;
}
cout << endl;
return 0;
}
结论:不同的方法都可以达到遍历效果。
6.字符串操作
6.1 operator+=
#include
#include
using namespace std;
int main() {
string s0("hello world!");
string s1("aa");
const char* p = "***";
s1 += s0;
s1 += p;
s1 += '+';
cout << s1<
6.2 append
#include
#include
using namespace std;
int main() {
string s1("hello world!");
const char* s2 = "bye";
s1.append( s2, 10);
s1.append(3,'c');
s1.append("hello");
cout << s1 << endl;
return 0;
}
6.3 push_back
#include
#include
using namespace std;
int main() {
string s1("hello world!");
const char* s2 = "bye";
s1.push_back('c');
cout << s1 << endl;
return 0;
}
6.4 insert && erase
#include
#include
using namespace std;
int main() {
string s1("hello world!");
s1.insert(6, "!!! ", 4);
s1.erase(6,4);
return 0;
}
6.5swap
#include
#include
using namespace std;
int main() {
string s1("hello world!");
string s2;
s2.swap(s1);
return 0;
}
7.string模拟实现
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
namespace str {
class string {
public:
typedef char* iterator;
typedef char* reverse_iterator;
//构造函数
string(const char* a="") {
if (a == nullptr) {
assert(false);
}
_size = strlen(a);
_str = new char[_size + 1];
strcpy(_str, a);
_capcity = _size;
}
string(size_t n,char s) {
_str = new char[n+1];
memset(_str,s,n);
*(_str + n) = ' ';
_size = n;
_capcity = n;
}
string(const string& s)
:_str(nullptr)
{
///解决方式:深拷贝//
string tmp(s._str);
this->swap(tmp);
}
~string() {
if (_str) {
delete[] _str;
_str = nullptr;
_size = 0;
_capcity = 0;
}
}
//赋值运算符重载
string& operator=(string s) {
swap(s);
return *this;
}
//迭代器
iterator begin() {
return this->_str;
}
iterator end() {
return _str + _size;
}
reverse_iterator rbegin() {
return _str+_size;
}
reverse_iterator rend() {
return _str;
}
//capcity相关
size_t size()const {
return _size;
}
size_t length()const {
return _size;
}
size_t capcity()const {
return _capcity;
}
bool empty()const {
if (_size == 0) {
return true;
}
return false;
}
void resize(size_t newsize,char s) {
size_t oldsize = size();
if (newsize < 0) {
assert(0);
}
if (newsize <= oldsize) {
_str[newsize] = ' ';
}
else {
if ( newsize > _capcity) {
reserve(newsize);
}
append(newsize - oldsize, s);
}
_size = newsize;
}
void reserve(size_t newsize) {
if (newsize > _capcity) {
char* tem = new char[newsize+1];
strcpy(tem,_str);
delete[] _str;
_str=tem;
_capcity = newsize;
}
}
//访问相关
//modify相关
string& append(size_t n,char a) {
if (n + _size > _capcity) {
reserve(n + _size);
}
memset(_str+_size, a, n);
_str[_size + n] = ' ';
_size = n + _size;
return *this;
}
string& append(const char* str) {
size_t len=strlen(str);
if (len + _size > _capcity) {
reserve(len + _size);
}
strcat(_str,str);
_size = len + _size;
return *this;
}
//Element acess
char& operator[](size_t index) {
assert(index < _size);
return _str[index];
}
const char& operator[](size_t index)const {
assert(index < _size);
return _str[index];
}
/modify
void push_back(char s) {
append(1,s);
}
string& operator+=(const string& s) {
append(s._str);
return *this;
}
string& operator+=(const char* str) {
append(str);
return *this;
}
//insert erase swap
string& insert(size_t pos,const string& s) {
size_t len = strlen(s._str);
char* p=s._str;
if (len + _size > _capcity) {
reserve(len+_size);
}
for (int i = _size+len; i>=pos; i--) {
_str[i+len] = _str[i];
}
while (*p != ' ') {
_str[pos] = *p;
p++;
}
return *this;
}
string& earse(size_t pos,size_t n) {
assert(pos<_size);
while (_str[pos] != ' ') {
_str[pos] = _str[pos + 1];
}
return *this;
}
///string operator
size_t find(char ch, size_t pos = 0) {
for (size_t i = pos; i < _size; i++) {
if (ch==_str[i]) {
return i;
}
}
return npos;
}
size_t rfind(char ch, size_t pos = npos) {
if (pos == npos) {
pos = _size - 1;
}
for (int i = _size-1; i >=0; i--) {
if (ch == _str[i]) {
return i;
}
}
return npos;
}
string substr(size_t pos = 0, size_t n =npos) {
if (n == npos) {
n = _size - pos;
}
char* tmp = new char[n + 1];
strncpy(tmp, _str + pos, n);
tmp[n] = ' ';
string strret(tmp);
delete[] tmp;
return strret;
}
void swap(string& s) {
std::swap(_str,s._str);
std::swap(_size, s._size);
std::swap(_capcity, s._capcity);
}
friend ostream& operator<<(ostream& _cout, const string& s)
{
_cout << s._str;
return _cout;
}
private:
char* _str;
size_t _size;
size_t _capcity;
static size_t npos;
};
size_t string::npos = -1;
void TestString1()
{
str::string s1;
str::string s2("hello");
str::string s3(s2);
str::string s4(10, 'A');
cout << s4.size() << std::endl;
cout << s2 << endl;
for (auto e : s3)
cout << e;
cout << endl;
auto it = s4.begin();
while (it != s4.end())
{
cout << *it;
++it;
}
cout << endl;
}
void TestString2()
{
str::string s("hello");
s.resize(10, '!');
std::cout << s << std::endl;
s.resize(7, '!');
}
void TestString3()
{
str::string s("abc.cpp");
str::string ret = s.substr(s.rfind('.') + 1);
cout << ret << endl;
}
}
int main() {
str::TestString1();
str::TestString2();
str::TestString3();
return 0;
}
#include#include using namespace std; int main() { const char* arr = "world"; string s0("hello"); string s1(s0); string s2(s0,0,2); string s3(10,'a'); string s4(arr, 3); string s5(s0.begin(), s0.begin() + 3); ~string(); return 0; }
begin() 和end()
begin()和end()目前可以看成两个指针,begin()指向字符串的头部,end()指向字符串尾部的下一个位置,即 的位置。我们可以使用begin()和end()进行遍历操作和获取位置操作。
rbegin(),rend()
rbegin()和rend()正好与上边的begin() 和end()相反,rbegin()指向字符串的尾部,即 的位置,rbegin()指向字符串头部。
#include#include using namespace std; int main() { string s0("hello world!"); string s1(s0.begin(), s0.end()); string s2(s0.rbegin(), s0.rend()); return 0; }
3.容量相关
size:字符串中有效元素的个数,不包括
capcity:字符串底层顺序表的空间的大小
size_t size() const;
此方法可以求字符串的长度,和C语言中length()方法相似
size_t capacity() const;
此方法可以查看顺序表实际上内部容量,因为string是可以自己扩容的,所以他的容量一定比存储的字符串多,当拷贝的字符串大于capacity时,String底层动态扩容。
void resize (size_t n); void resize (size_t n, char c);
此函数作用是更新有效元素个数,当nsize && ncapcity,则编译器会先申请一块大于n的空间,然后将原来字符串拷贝进去,使用参数c填充,再销毁原空间。
void reserve (size_t n );
此方法可以调整顺序表的容量大小,不会修改有效元素个数,此函数作用是将字符串容量变为n个,当n大于capcity时正常扩容; 当n小于原来capcity且大于有效元素个数时(size),则缩减capcity; 当n小于有效元素个数时,编译器忽略这条指令。
void clear();
清空有效元素,但是不改变capcity大小
bool empty() const;
检测这个字符串是否为空,空则返回true,非空则返回false;
4.元素访问相关
operator[]
char& operator[] (size_t pos); const char& operator[] (size_t pos) const;
string底层就是一个字符数组,所以可以像访问数组一样使用[]访问字符串。
at
char& at (size_t pos); const char& at (size_t pos) const;
at和[]在使用效果方面完全一致,使用方法举例 cout << str.at(i);
区别:[]在越界访问时会触发assert断言,at会抛出异常,可供用户捕获。
5.元素遍历相关
1.for循环
2.范围for
3.迭代器
#include
#include
using namespace std;
int main() {
string s0("hello world!");
//for循环
for (int i = 0; i < s0.size(); i++) {
cout << s0[i];
}
cout << endl;
//范围for
for (auto e : s0) {
cout << e;
}
cout << endl;
//迭代器
string::iterator it = s0.begin();
while (it !=s0.end()) {
cout << *it;
it++;
}
cout << endl;
return 0;
}
结论:不同的方法都可以达到遍历效果。
6.字符串操作
6.1 operator+=
#include
#include
using namespace std;
int main() {
string s0("hello world!");
string s1("aa");
const char* p = "***";
s1 += s0;
s1 += p;
s1 += '+';
cout << s1<
6.2 append
#include
#include
using namespace std;
int main() {
string s1("hello world!");
const char* s2 = "bye";
s1.append( s2, 10);
s1.append(3,'c');
s1.append("hello");
cout << s1 << endl;
return 0;
}
6.3 push_back
#include
#include
using namespace std;
int main() {
string s1("hello world!");
const char* s2 = "bye";
s1.push_back('c');
cout << s1 << endl;
return 0;
}
6.4 insert && erase
#include
#include
using namespace std;
int main() {
string s1("hello world!");
s1.insert(6, "!!! ", 4);
s1.erase(6,4);
return 0;
}
6.5swap
#include
#include
using namespace std;
int main() {
string s1("hello world!");
string s2;
s2.swap(s1);
return 0;
}
7.string模拟实现
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
namespace str {
class string {
public:
typedef char* iterator;
typedef char* reverse_iterator;
//构造函数
string(const char* a="") {
if (a == nullptr) {
assert(false);
}
_size = strlen(a);
_str = new char[_size + 1];
strcpy(_str, a);
_capcity = _size;
}
string(size_t n,char s) {
_str = new char[n+1];
memset(_str,s,n);
*(_str + n) = ' ';
_size = n;
_capcity = n;
}
string(const string& s)
:_str(nullptr)
{
///解决方式:深拷贝//
string tmp(s._str);
this->swap(tmp);
}
~string() {
if (_str) {
delete[] _str;
_str = nullptr;
_size = 0;
_capcity = 0;
}
}
//赋值运算符重载
string& operator=(string s) {
swap(s);
return *this;
}
//迭代器
iterator begin() {
return this->_str;
}
iterator end() {
return _str + _size;
}
reverse_iterator rbegin() {
return _str+_size;
}
reverse_iterator rend() {
return _str;
}
//capcity相关
size_t size()const {
return _size;
}
size_t length()const {
return _size;
}
size_t capcity()const {
return _capcity;
}
bool empty()const {
if (_size == 0) {
return true;
}
return false;
}
void resize(size_t newsize,char s) {
size_t oldsize = size();
if (newsize < 0) {
assert(0);
}
if (newsize <= oldsize) {
_str[newsize] = ' ';
}
else {
if ( newsize > _capcity) {
reserve(newsize);
}
append(newsize - oldsize, s);
}
_size = newsize;
}
void reserve(size_t newsize) {
if (newsize > _capcity) {
char* tem = new char[newsize+1];
strcpy(tem,_str);
delete[] _str;
_str=tem;
_capcity = newsize;
}
}
//访问相关
//modify相关
string& append(size_t n,char a) {
if (n + _size > _capcity) {
reserve(n + _size);
}
memset(_str+_size, a, n);
_str[_size + n] = ' ';
_size = n + _size;
return *this;
}
string& append(const char* str) {
size_t len=strlen(str);
if (len + _size > _capcity) {
reserve(len + _size);
}
strcat(_str,str);
_size = len + _size;
return *this;
}
//Element acess
char& operator[](size_t index) {
assert(index < _size);
return _str[index];
}
const char& operator[](size_t index)const {
assert(index < _size);
return _str[index];
}
/modify
void push_back(char s) {
append(1,s);
}
string& operator+=(const string& s) {
append(s._str);
return *this;
}
string& operator+=(const char* str) {
append(str);
return *this;
}
//insert erase swap
string& insert(size_t pos,const string& s) {
size_t len = strlen(s._str);
char* p=s._str;
if (len + _size > _capcity) {
reserve(len+_size);
}
for (int i = _size+len; i>=pos; i--) {
_str[i+len] = _str[i];
}
while (*p != ' ') {
_str[pos] = *p;
p++;
}
return *this;
}
string& earse(size_t pos,size_t n) {
assert(pos<_size);
while (_str[pos] != ' ') {
_str[pos] = _str[pos + 1];
}
return *this;
}
///string operator
size_t find(char ch, size_t pos = 0) {
for (size_t i = pos; i < _size; i++) {
if (ch==_str[i]) {
return i;
}
}
return npos;
}
size_t rfind(char ch, size_t pos = npos) {
if (pos == npos) {
pos = _size - 1;
}
for (int i = _size-1; i >=0; i--) {
if (ch == _str[i]) {
return i;
}
}
return npos;
}
string substr(size_t pos = 0, size_t n =npos) {
if (n == npos) {
n = _size - pos;
}
char* tmp = new char[n + 1];
strncpy(tmp, _str + pos, n);
tmp[n] = ' ';
string strret(tmp);
delete[] tmp;
return strret;
}
void swap(string& s) {
std::swap(_str,s._str);
std::swap(_size, s._size);
std::swap(_capcity, s._capcity);
}
friend ostream& operator<<(ostream& _cout, const string& s)
{
_cout << s._str;
return _cout;
}
private:
char* _str;
size_t _size;
size_t _capcity;
static size_t npos;
};
size_t string::npos = -1;
void TestString1()
{
str::string s1;
str::string s2("hello");
str::string s3(s2);
str::string s4(10, 'A');
cout << s4.size() << std::endl;
cout << s2 << endl;
for (auto e : s3)
cout << e;
cout << endl;
auto it = s4.begin();
while (it != s4.end())
{
cout << *it;
++it;
}
cout << endl;
}
void TestString2()
{
str::string s("hello");
s.resize(10, '!');
std::cout << s << std::endl;
s.resize(7, '!');
}
void TestString3()
{
str::string s("abc.cpp");
str::string ret = s.substr(s.rfind('.') + 1);
cout << ret << endl;
}
}
int main() {
str::TestString1();
str::TestString2();
str::TestString3();
return 0;
}
size:字符串中有效元素的个数,不包括 capcity:字符串底层顺序表的空间的大小 size_t size() const;
此方法可以求字符串的长度,和C语言中length()方法相似
size_t capacity() const;
此方法可以查看顺序表实际上内部容量,因为string是可以自己扩容的,所以他的容量一定比存储的字符串多,当拷贝的字符串大于capacity时,String底层动态扩容。
void resize (size_t n); void resize (size_t n, char c);
此函数作用是更新有效元素个数,当n
void reserve (size_t n );
此方法可以调整顺序表的容量大小,不会修改有效元素个数,此函数作用是将字符串容量变为n个,当n大于capcity时正常扩容; 当n小于原来capcity且大于有效元素个数时(size),则缩减capcity; 当n小于有效元素个数时,编译器忽略这条指令。
void clear();
清空有效元素,但是不改变capcity大小
bool empty() const;
检测这个字符串是否为空,空则返回true,非空则返回false;
operator[]
char& operator[] (size_t pos); const char& operator[] (size_t pos) const;
string底层就是一个字符数组,所以可以像访问数组一样使用[]访问字符串。
at
char& at (size_t pos); const char& at (size_t pos) const;
at和[]在使用效果方面完全一致,使用方法举例 cout << str.at(i);
区别:[]在越界访问时会触发assert断言,at会抛出异常,可供用户捕获。
5.元素遍历相关
1.for循环
2.范围for
3.迭代器
#include
#include
using namespace std;
int main() {
string s0("hello world!");
//for循环
for (int i = 0; i < s0.size(); i++) {
cout << s0[i];
}
cout << endl;
//范围for
for (auto e : s0) {
cout << e;
}
cout << endl;
//迭代器
string::iterator it = s0.begin();
while (it !=s0.end()) {
cout << *it;
it++;
}
cout << endl;
return 0;
}
结论:不同的方法都可以达到遍历效果。
6.字符串操作
6.1 operator+=
#include
#include
using namespace std;
int main() {
string s0("hello world!");
string s1("aa");
const char* p = "***";
s1 += s0;
s1 += p;
s1 += '+';
cout << s1<
6.2 append
#include
#include
using namespace std;
int main() {
string s1("hello world!");
const char* s2 = "bye";
s1.append( s2, 10);
s1.append(3,'c');
s1.append("hello");
cout << s1 << endl;
return 0;
}
6.3 push_back
#include
#include
using namespace std;
int main() {
string s1("hello world!");
const char* s2 = "bye";
s1.push_back('c');
cout << s1 << endl;
return 0;
}
6.4 insert && erase
#include
#include
using namespace std;
int main() {
string s1("hello world!");
s1.insert(6, "!!! ", 4);
s1.erase(6,4);
return 0;
}
6.5swap
#include
#include
using namespace std;
int main() {
string s1("hello world!");
string s2;
s2.swap(s1);
return 0;
}
7.string模拟实现
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
namespace str {
class string {
public:
typedef char* iterator;
typedef char* reverse_iterator;
//构造函数
string(const char* a="") {
if (a == nullptr) {
assert(false);
}
_size = strlen(a);
_str = new char[_size + 1];
strcpy(_str, a);
_capcity = _size;
}
string(size_t n,char s) {
_str = new char[n+1];
memset(_str,s,n);
*(_str + n) = ' ';
_size = n;
_capcity = n;
}
string(const string& s)
:_str(nullptr)
{
///解决方式:深拷贝//
string tmp(s._str);
this->swap(tmp);
}
~string() {
if (_str) {
delete[] _str;
_str = nullptr;
_size = 0;
_capcity = 0;
}
}
//赋值运算符重载
string& operator=(string s) {
swap(s);
return *this;
}
//迭代器
iterator begin() {
return this->_str;
}
iterator end() {
return _str + _size;
}
reverse_iterator rbegin() {
return _str+_size;
}
reverse_iterator rend() {
return _str;
}
//capcity相关
size_t size()const {
return _size;
}
size_t length()const {
return _size;
}
size_t capcity()const {
return _capcity;
}
bool empty()const {
if (_size == 0) {
return true;
}
return false;
}
void resize(size_t newsize,char s) {
size_t oldsize = size();
if (newsize < 0) {
assert(0);
}
if (newsize <= oldsize) {
_str[newsize] = ' ';
}
else {
if ( newsize > _capcity) {
reserve(newsize);
}
append(newsize - oldsize, s);
}
_size = newsize;
}
void reserve(size_t newsize) {
if (newsize > _capcity) {
char* tem = new char[newsize+1];
strcpy(tem,_str);
delete[] _str;
_str=tem;
_capcity = newsize;
}
}
//访问相关
//modify相关
string& append(size_t n,char a) {
if (n + _size > _capcity) {
reserve(n + _size);
}
memset(_str+_size, a, n);
_str[_size + n] = ' ';
_size = n + _size;
return *this;
}
string& append(const char* str) {
size_t len=strlen(str);
if (len + _size > _capcity) {
reserve(len + _size);
}
strcat(_str,str);
_size = len + _size;
return *this;
}
//Element acess
char& operator[](size_t index) {
assert(index < _size);
return _str[index];
}
const char& operator[](size_t index)const {
assert(index < _size);
return _str[index];
}
/modify
void push_back(char s) {
append(1,s);
}
string& operator+=(const string& s) {
append(s._str);
return *this;
}
string& operator+=(const char* str) {
append(str);
return *this;
}
//insert erase swap
string& insert(size_t pos,const string& s) {
size_t len = strlen(s._str);
char* p=s._str;
if (len + _size > _capcity) {
reserve(len+_size);
}
for (int i = _size+len; i>=pos; i--) {
_str[i+len] = _str[i];
}
while (*p != ' ') {
_str[pos] = *p;
p++;
}
return *this;
}
string& earse(size_t pos,size_t n) {
assert(pos<_size);
while (_str[pos] != ' ') {
_str[pos] = _str[pos + 1];
}
return *this;
}
///string operator
size_t find(char ch, size_t pos = 0) {
for (size_t i = pos; i < _size; i++) {
if (ch==_str[i]) {
return i;
}
}
return npos;
}
size_t rfind(char ch, size_t pos = npos) {
if (pos == npos) {
pos = _size - 1;
}
for (int i = _size-1; i >=0; i--) {
if (ch == _str[i]) {
return i;
}
}
return npos;
}
string substr(size_t pos = 0, size_t n =npos) {
if (n == npos) {
n = _size - pos;
}
char* tmp = new char[n + 1];
strncpy(tmp, _str + pos, n);
tmp[n] = ' ';
string strret(tmp);
delete[] tmp;
return strret;
}
void swap(string& s) {
std::swap(_str,s._str);
std::swap(_size, s._size);
std::swap(_capcity, s._capcity);
}
friend ostream& operator<<(ostream& _cout, const string& s)
{
_cout << s._str;
return _cout;
}
private:
char* _str;
size_t _size;
size_t _capcity;
static size_t npos;
};
size_t string::npos = -1;
void TestString1()
{
str::string s1;
str::string s2("hello");
str::string s3(s2);
str::string s4(10, 'A');
cout << s4.size() << std::endl;
cout << s2 << endl;
for (auto e : s3)
cout << e;
cout << endl;
auto it = s4.begin();
while (it != s4.end())
{
cout << *it;
++it;
}
cout << endl;
}
void TestString2()
{
str::string s("hello");
s.resize(10, '!');
std::cout << s << std::endl;
s.resize(7, '!');
}
void TestString3()
{
str::string s("abc.cpp");
str::string ret = s.substr(s.rfind('.') + 1);
cout << ret << endl;
}
}
int main() {
str::TestString1();
str::TestString2();
str::TestString3();
return 0;
}
1.for循环
2.范围for
3.迭代器
#include#include using namespace std; int main() { string s0("hello world!"); //for循环 for (int i = 0; i < s0.size(); i++) { cout << s0[i]; } cout << endl; //范围for for (auto e : s0) { cout << e; } cout << endl; //迭代器 string::iterator it = s0.begin(); while (it !=s0.end()) { cout << *it; it++; } cout << endl; return 0; }
结论:不同的方法都可以达到遍历效果。
6.1 operator+=
#include
#include
using namespace std;
int main() {
string s0("hello world!");
string s1("aa");
const char* p = "***";
s1 += s0;
s1 += p;
s1 += '+';
cout << s1<
6.2 append
#include
#include
using namespace std;
int main() {
string s1("hello world!");
const char* s2 = "bye";
s1.append( s2, 10);
s1.append(3,'c');
s1.append("hello");
cout << s1 << endl;
return 0;
}
6.3 push_back
#include
#include
using namespace std;
int main() {
string s1("hello world!");
const char* s2 = "bye";
s1.push_back('c');
cout << s1 << endl;
return 0;
}
6.4 insert && erase
#include
#include
using namespace std;
int main() {
string s1("hello world!");
s1.insert(6, "!!! ", 4);
s1.erase(6,4);
return 0;
}
6.5swap
#include
#include
using namespace std;
int main() {
string s1("hello world!");
string s2;
s2.swap(s1);
return 0;
}
7.string模拟实现
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
namespace str {
class string {
public:
typedef char* iterator;
typedef char* reverse_iterator;
//构造函数
string(const char* a="") {
if (a == nullptr) {
assert(false);
}
_size = strlen(a);
_str = new char[_size + 1];
strcpy(_str, a);
_capcity = _size;
}
string(size_t n,char s) {
_str = new char[n+1];
memset(_str,s,n);
*(_str + n) = ' ';
_size = n;
_capcity = n;
}
string(const string& s)
:_str(nullptr)
{
///解决方式:深拷贝//
string tmp(s._str);
this->swap(tmp);
}
~string() {
if (_str) {
delete[] _str;
_str = nullptr;
_size = 0;
_capcity = 0;
}
}
//赋值运算符重载
string& operator=(string s) {
swap(s);
return *this;
}
//迭代器
iterator begin() {
return this->_str;
}
iterator end() {
return _str + _size;
}
reverse_iterator rbegin() {
return _str+_size;
}
reverse_iterator rend() {
return _str;
}
//capcity相关
size_t size()const {
return _size;
}
size_t length()const {
return _size;
}
size_t capcity()const {
return _capcity;
}
bool empty()const {
if (_size == 0) {
return true;
}
return false;
}
void resize(size_t newsize,char s) {
size_t oldsize = size();
if (newsize < 0) {
assert(0);
}
if (newsize <= oldsize) {
_str[newsize] = ' ';
}
else {
if ( newsize > _capcity) {
reserve(newsize);
}
append(newsize - oldsize, s);
}
_size = newsize;
}
void reserve(size_t newsize) {
if (newsize > _capcity) {
char* tem = new char[newsize+1];
strcpy(tem,_str);
delete[] _str;
_str=tem;
_capcity = newsize;
}
}
//访问相关
//modify相关
string& append(size_t n,char a) {
if (n + _size > _capcity) {
reserve(n + _size);
}
memset(_str+_size, a, n);
_str[_size + n] = ' ';
_size = n + _size;
return *this;
}
string& append(const char* str) {
size_t len=strlen(str);
if (len + _size > _capcity) {
reserve(len + _size);
}
strcat(_str,str);
_size = len + _size;
return *this;
}
//Element acess
char& operator[](size_t index) {
assert(index < _size);
return _str[index];
}
const char& operator[](size_t index)const {
assert(index < _size);
return _str[index];
}
/modify
void push_back(char s) {
append(1,s);
}
string& operator+=(const string& s) {
append(s._str);
return *this;
}
string& operator+=(const char* str) {
append(str);
return *this;
}
//insert erase swap
string& insert(size_t pos,const string& s) {
size_t len = strlen(s._str);
char* p=s._str;
if (len + _size > _capcity) {
reserve(len+_size);
}
for (int i = _size+len; i>=pos; i--) {
_str[i+len] = _str[i];
}
while (*p != ' ') {
_str[pos] = *p;
p++;
}
return *this;
}
string& earse(size_t pos,size_t n) {
assert(pos<_size);
while (_str[pos] != ' ') {
_str[pos] = _str[pos + 1];
}
return *this;
}
///string operator
size_t find(char ch, size_t pos = 0) {
for (size_t i = pos; i < _size; i++) {
if (ch==_str[i]) {
return i;
}
}
return npos;
}
size_t rfind(char ch, size_t pos = npos) {
if (pos == npos) {
pos = _size - 1;
}
for (int i = _size-1; i >=0; i--) {
if (ch == _str[i]) {
return i;
}
}
return npos;
}
string substr(size_t pos = 0, size_t n =npos) {
if (n == npos) {
n = _size - pos;
}
char* tmp = new char[n + 1];
strncpy(tmp, _str + pos, n);
tmp[n] = ' ';
string strret(tmp);
delete[] tmp;
return strret;
}
void swap(string& s) {
std::swap(_str,s._str);
std::swap(_size, s._size);
std::swap(_capcity, s._capcity);
}
friend ostream& operator<<(ostream& _cout, const string& s)
{
_cout << s._str;
return _cout;
}
private:
char* _str;
size_t _size;
size_t _capcity;
static size_t npos;
};
size_t string::npos = -1;
void TestString1()
{
str::string s1;
str::string s2("hello");
str::string s3(s2);
str::string s4(10, 'A');
cout << s4.size() << std::endl;
cout << s2 << endl;
for (auto e : s3)
cout << e;
cout << endl;
auto it = s4.begin();
while (it != s4.end())
{
cout << *it;
++it;
}
cout << endl;
}
void TestString2()
{
str::string s("hello");
s.resize(10, '!');
std::cout << s << std::endl;
s.resize(7, '!');
}
void TestString3()
{
str::string s("abc.cpp");
str::string ret = s.substr(s.rfind('.') + 1);
cout << ret << endl;
}
}
int main() {
str::TestString1();
str::TestString2();
str::TestString3();
return 0;
}
#include#include using namespace std; int main() { string s0("hello world!"); string s1("aa"); const char* p = "***"; s1 += s0; s1 += p; s1 += '+'; cout << s1<
#include#include using namespace std; int main() { string s1("hello world!"); const char* s2 = "bye"; s1.append( s2, 10); s1.append(3,'c'); s1.append("hello"); cout << s1 << endl; return 0; }
6.3 push_back
#include
#include
using namespace std;
int main() {
string s1("hello world!");
const char* s2 = "bye";
s1.push_back('c');
cout << s1 << endl;
return 0;
}
6.4 insert && erase
#include
#include
using namespace std;
int main() {
string s1("hello world!");
s1.insert(6, "!!! ", 4);
s1.erase(6,4);
return 0;
}
6.5swap
#include
#include
using namespace std;
int main() {
string s1("hello world!");
string s2;
s2.swap(s1);
return 0;
}
7.string模拟实现
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
namespace str {
class string {
public:
typedef char* iterator;
typedef char* reverse_iterator;
//构造函数
string(const char* a="") {
if (a == nullptr) {
assert(false);
}
_size = strlen(a);
_str = new char[_size + 1];
strcpy(_str, a);
_capcity = _size;
}
string(size_t n,char s) {
_str = new char[n+1];
memset(_str,s,n);
*(_str + n) = ' ';
_size = n;
_capcity = n;
}
string(const string& s)
:_str(nullptr)
{
///解决方式:深拷贝//
string tmp(s._str);
this->swap(tmp);
}
~string() {
if (_str) {
delete[] _str;
_str = nullptr;
_size = 0;
_capcity = 0;
}
}
//赋值运算符重载
string& operator=(string s) {
swap(s);
return *this;
}
//迭代器
iterator begin() {
return this->_str;
}
iterator end() {
return _str + _size;
}
reverse_iterator rbegin() {
return _str+_size;
}
reverse_iterator rend() {
return _str;
}
//capcity相关
size_t size()const {
return _size;
}
size_t length()const {
return _size;
}
size_t capcity()const {
return _capcity;
}
bool empty()const {
if (_size == 0) {
return true;
}
return false;
}
void resize(size_t newsize,char s) {
size_t oldsize = size();
if (newsize < 0) {
assert(0);
}
if (newsize <= oldsize) {
_str[newsize] = ' ';
}
else {
if ( newsize > _capcity) {
reserve(newsize);
}
append(newsize - oldsize, s);
}
_size = newsize;
}
void reserve(size_t newsize) {
if (newsize > _capcity) {
char* tem = new char[newsize+1];
strcpy(tem,_str);
delete[] _str;
_str=tem;
_capcity = newsize;
}
}
//访问相关
//modify相关
string& append(size_t n,char a) {
if (n + _size > _capcity) {
reserve(n + _size);
}
memset(_str+_size, a, n);
_str[_size + n] = ' ';
_size = n + _size;
return *this;
}
string& append(const char* str) {
size_t len=strlen(str);
if (len + _size > _capcity) {
reserve(len + _size);
}
strcat(_str,str);
_size = len + _size;
return *this;
}
//Element acess
char& operator[](size_t index) {
assert(index < _size);
return _str[index];
}
const char& operator[](size_t index)const {
assert(index < _size);
return _str[index];
}
/modify
void push_back(char s) {
append(1,s);
}
string& operator+=(const string& s) {
append(s._str);
return *this;
}
string& operator+=(const char* str) {
append(str);
return *this;
}
//insert erase swap
string& insert(size_t pos,const string& s) {
size_t len = strlen(s._str);
char* p=s._str;
if (len + _size > _capcity) {
reserve(len+_size);
}
for (int i = _size+len; i>=pos; i--) {
_str[i+len] = _str[i];
}
while (*p != ' ') {
_str[pos] = *p;
p++;
}
return *this;
}
string& earse(size_t pos,size_t n) {
assert(pos<_size);
while (_str[pos] != ' ') {
_str[pos] = _str[pos + 1];
}
return *this;
}
///string operator
size_t find(char ch, size_t pos = 0) {
for (size_t i = pos; i < _size; i++) {
if (ch==_str[i]) {
return i;
}
}
return npos;
}
size_t rfind(char ch, size_t pos = npos) {
if (pos == npos) {
pos = _size - 1;
}
for (int i = _size-1; i >=0; i--) {
if (ch == _str[i]) {
return i;
}
}
return npos;
}
string substr(size_t pos = 0, size_t n =npos) {
if (n == npos) {
n = _size - pos;
}
char* tmp = new char[n + 1];
strncpy(tmp, _str + pos, n);
tmp[n] = ' ';
string strret(tmp);
delete[] tmp;
return strret;
}
void swap(string& s) {
std::swap(_str,s._str);
std::swap(_size, s._size);
std::swap(_capcity, s._capcity);
}
friend ostream& operator<<(ostream& _cout, const string& s)
{
_cout << s._str;
return _cout;
}
private:
char* _str;
size_t _size;
size_t _capcity;
static size_t npos;
};
size_t string::npos = -1;
void TestString1()
{
str::string s1;
str::string s2("hello");
str::string s3(s2);
str::string s4(10, 'A');
cout << s4.size() << std::endl;
cout << s2 << endl;
for (auto e : s3)
cout << e;
cout << endl;
auto it = s4.begin();
while (it != s4.end())
{
cout << *it;
++it;
}
cout << endl;
}
void TestString2()
{
str::string s("hello");
s.resize(10, '!');
std::cout << s << std::endl;
s.resize(7, '!');
}
void TestString3()
{
str::string s("abc.cpp");
str::string ret = s.substr(s.rfind('.') + 1);
cout << ret << endl;
}
}
int main() {
str::TestString1();
str::TestString2();
str::TestString3();
return 0;
}
#include#include using namespace std; int main() { string s1("hello world!"); const char* s2 = "bye"; s1.push_back('c'); cout << s1 << endl; return 0; }
#include#include using namespace std; int main() { string s1("hello world!"); s1.insert(6, "!!! ", 4); s1.erase(6,4); return 0; }
6.5swap
#include
#include
using namespace std;
int main() {
string s1("hello world!");
string s2;
s2.swap(s1);
return 0;
}
7.string模拟实现
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
namespace str {
class string {
public:
typedef char* iterator;
typedef char* reverse_iterator;
//构造函数
string(const char* a="") {
if (a == nullptr) {
assert(false);
}
_size = strlen(a);
_str = new char[_size + 1];
strcpy(_str, a);
_capcity = _size;
}
string(size_t n,char s) {
_str = new char[n+1];
memset(_str,s,n);
*(_str + n) = ' ';
_size = n;
_capcity = n;
}
string(const string& s)
:_str(nullptr)
{
///解决方式:深拷贝//
string tmp(s._str);
this->swap(tmp);
}
~string() {
if (_str) {
delete[] _str;
_str = nullptr;
_size = 0;
_capcity = 0;
}
}
//赋值运算符重载
string& operator=(string s) {
swap(s);
return *this;
}
//迭代器
iterator begin() {
return this->_str;
}
iterator end() {
return _str + _size;
}
reverse_iterator rbegin() {
return _str+_size;
}
reverse_iterator rend() {
return _str;
}
//capcity相关
size_t size()const {
return _size;
}
size_t length()const {
return _size;
}
size_t capcity()const {
return _capcity;
}
bool empty()const {
if (_size == 0) {
return true;
}
return false;
}
void resize(size_t newsize,char s) {
size_t oldsize = size();
if (newsize < 0) {
assert(0);
}
if (newsize <= oldsize) {
_str[newsize] = ' ';
}
else {
if ( newsize > _capcity) {
reserve(newsize);
}
append(newsize - oldsize, s);
}
_size = newsize;
}
void reserve(size_t newsize) {
if (newsize > _capcity) {
char* tem = new char[newsize+1];
strcpy(tem,_str);
delete[] _str;
_str=tem;
_capcity = newsize;
}
}
//访问相关
//modify相关
string& append(size_t n,char a) {
if (n + _size > _capcity) {
reserve(n + _size);
}
memset(_str+_size, a, n);
_str[_size + n] = ' ';
_size = n + _size;
return *this;
}
string& append(const char* str) {
size_t len=strlen(str);
if (len + _size > _capcity) {
reserve(len + _size);
}
strcat(_str,str);
_size = len + _size;
return *this;
}
//Element acess
char& operator[](size_t index) {
assert(index < _size);
return _str[index];
}
const char& operator[](size_t index)const {
assert(index < _size);
return _str[index];
}
/modify
void push_back(char s) {
append(1,s);
}
string& operator+=(const string& s) {
append(s._str);
return *this;
}
string& operator+=(const char* str) {
append(str);
return *this;
}
//insert erase swap
string& insert(size_t pos,const string& s) {
size_t len = strlen(s._str);
char* p=s._str;
if (len + _size > _capcity) {
reserve(len+_size);
}
for (int i = _size+len; i>=pos; i--) {
_str[i+len] = _str[i];
}
while (*p != ' ') {
_str[pos] = *p;
p++;
}
return *this;
}
string& earse(size_t pos,size_t n) {
assert(pos<_size);
while (_str[pos] != ' ') {
_str[pos] = _str[pos + 1];
}
return *this;
}
///string operator
size_t find(char ch, size_t pos = 0) {
for (size_t i = pos; i < _size; i++) {
if (ch==_str[i]) {
return i;
}
}
return npos;
}
size_t rfind(char ch, size_t pos = npos) {
if (pos == npos) {
pos = _size - 1;
}
for (int i = _size-1; i >=0; i--) {
if (ch == _str[i]) {
return i;
}
}
return npos;
}
string substr(size_t pos = 0, size_t n =npos) {
if (n == npos) {
n = _size - pos;
}
char* tmp = new char[n + 1];
strncpy(tmp, _str + pos, n);
tmp[n] = ' ';
string strret(tmp);
delete[] tmp;
return strret;
}
void swap(string& s) {
std::swap(_str,s._str);
std::swap(_size, s._size);
std::swap(_capcity, s._capcity);
}
friend ostream& operator<<(ostream& _cout, const string& s)
{
_cout << s._str;
return _cout;
}
private:
char* _str;
size_t _size;
size_t _capcity;
static size_t npos;
};
size_t string::npos = -1;
void TestString1()
{
str::string s1;
str::string s2("hello");
str::string s3(s2);
str::string s4(10, 'A');
cout << s4.size() << std::endl;
cout << s2 << endl;
for (auto e : s3)
cout << e;
cout << endl;
auto it = s4.begin();
while (it != s4.end())
{
cout << *it;
++it;
}
cout << endl;
}
void TestString2()
{
str::string s("hello");
s.resize(10, '!');
std::cout << s << std::endl;
s.resize(7, '!');
}
void TestString3()
{
str::string s("abc.cpp");
str::string ret = s.substr(s.rfind('.') + 1);
cout << ret << endl;
}
}
int main() {
str::TestString1();
str::TestString2();
str::TestString3();
return 0;
}
#include#include using namespace std; int main() { string s1("hello world!"); string s2; s2.swap(s1); return 0; }
#define _CRT_SECURE_NO_WARNINGS #include#include using namespace std; namespace str { class string { public: typedef char* iterator; typedef char* reverse_iterator; //构造函数 string(const char* a="") { if (a == nullptr) { assert(false); } _size = strlen(a); _str = new char[_size + 1]; strcpy(_str, a); _capcity = _size; } string(size_t n,char s) { _str = new char[n+1]; memset(_str,s,n); *(_str + n) = ' '; _size = n; _capcity = n; } string(const string& s) :_str(nullptr) { ///解决方式:深拷贝// string tmp(s._str); this->swap(tmp); } ~string() { if (_str) { delete[] _str; _str = nullptr; _size = 0; _capcity = 0; } } //赋值运算符重载 string& operator=(string s) { swap(s); return *this; } //迭代器 iterator begin() { return this->_str; } iterator end() { return _str + _size; } reverse_iterator rbegin() { return _str+_size; } reverse_iterator rend() { return _str; } //capcity相关 size_t size()const { return _size; } size_t length()const { return _size; } size_t capcity()const { return _capcity; } bool empty()const { if (_size == 0) { return true; } return false; } void resize(size_t newsize,char s) { size_t oldsize = size(); if (newsize < 0) { assert(0); } if (newsize <= oldsize) { _str[newsize] = ' '; } else { if ( newsize > _capcity) { reserve(newsize); } append(newsize - oldsize, s); } _size = newsize; } void reserve(size_t newsize) { if (newsize > _capcity) { char* tem = new char[newsize+1]; strcpy(tem,_str); delete[] _str; _str=tem; _capcity = newsize; } } //访问相关 //modify相关 string& append(size_t n,char a) { if (n + _size > _capcity) { reserve(n + _size); } memset(_str+_size, a, n); _str[_size + n] = ' '; _size = n + _size; return *this; } string& append(const char* str) { size_t len=strlen(str); if (len + _size > _capcity) { reserve(len + _size); } strcat(_str,str); _size = len + _size; return *this; } //Element acess char& operator[](size_t index) { assert(index < _size); return _str[index]; } const char& operator[](size_t index)const { assert(index < _size); return _str[index]; } /modify void push_back(char s) { append(1,s); } string& operator+=(const string& s) { append(s._str); return *this; } string& operator+=(const char* str) { append(str); return *this; } //insert erase swap string& insert(size_t pos,const string& s) { size_t len = strlen(s._str); char* p=s._str; if (len + _size > _capcity) { reserve(len+_size); } for (int i = _size+len; i>=pos; i--) { _str[i+len] = _str[i]; } while (*p != ' ') { _str[pos] = *p; p++; } return *this; } string& earse(size_t pos,size_t n) { assert(pos<_size); while (_str[pos] != ' ') { _str[pos] = _str[pos + 1]; } return *this; } ///string operator size_t find(char ch, size_t pos = 0) { for (size_t i = pos; i < _size; i++) { if (ch==_str[i]) { return i; } } return npos; } size_t rfind(char ch, size_t pos = npos) { if (pos == npos) { pos = _size - 1; } for (int i = _size-1; i >=0; i--) { if (ch == _str[i]) { return i; } } return npos; } string substr(size_t pos = 0, size_t n =npos) { if (n == npos) { n = _size - pos; } char* tmp = new char[n + 1]; strncpy(tmp, _str + pos, n); tmp[n] = ' '; string strret(tmp); delete[] tmp; return strret; } void swap(string& s) { std::swap(_str,s._str); std::swap(_size, s._size); std::swap(_capcity, s._capcity); } friend ostream& operator<<(ostream& _cout, const string& s) { _cout << s._str; return _cout; } private: char* _str; size_t _size; size_t _capcity; static size_t npos; }; size_t string::npos = -1; void TestString1() { str::string s1; str::string s2("hello"); str::string s3(s2); str::string s4(10, 'A'); cout << s4.size() << std::endl; cout << s2 << endl; for (auto e : s3) cout << e; cout << endl; auto it = s4.begin(); while (it != s4.end()) { cout << *it; ++it; } cout << endl; } void TestString2() { str::string s("hello"); s.resize(10, '!'); std::cout << s << std::endl; s.resize(7, '!'); } void TestString3() { str::string s("abc.cpp"); str::string ret = s.substr(s.rfind('.') + 1); cout << ret << endl; } } int main() { str::TestString1(); str::TestString2(); str::TestString3(); return 0; }



