【C++】string类中常用函数的模拟实现

六点半888 2024-09-17 10:35:28 阅读 69

【C++】string类中常用函数的模拟实现

1. string.h2. Text.cpp

1. string.h

<code>#pragma once

#include<assert.h>

namespace wch

{ -- -->

class string

{

public:

typedef char* iterator;

typedef const char* const_iterator;

iterator begin()

{

return _str;

}

iterator end()

{

return _str + _size;

}

const_iterator begin() const

{

return _str;

}

const_iterator end() const

{

return _str + _size;

}

//若使用初始化列表初始化要注意:初始化顺序为声明顺序

//构造函数无参对象初始化 string str;

string(const char* str = "")//string(const char* str = "\0")

{

_size = strlen(str);

_capacity = _size;

_str = new char[_capacity + 1];

memcpy(_str, str, _size + 1);

}

string(const string& s)//拷贝构造函数有参对象初始化 string str("abc");

{

_str = new char[s._capacity + 1];

memcpy(_str, s._str, s._size + 1);

_size = s._size;

_capacity = s._capacity;

}

// s1 = s3,传统写法

//string& operator=(const string& s)

//{

//if (this != &s)

//{

//char* tmp = new char[s._capacity + 1];

//memcpy(tmp, s._str, s._size+1);

//delete[] _str;

//_str = tmp;

//_size = s._size;

//_capacity = s._capacity;

//}

//return *this;

//}

//

//错误写法,调用swap函数时,由于在swap函数里面反复调用自定义赋值运算符造成栈溢出

//string& operator=(string tmp)

//{

//swap(tmp, *this);

//return *this;

//}

void swap(string & s)

{

std::swap(_str, s._str);

std::swap(_size, s._size);

std::swap(_capacity, s._capacity);

}

//现代写法,值传递调用拷贝构造

string& operator=(string tmp)

{

swap(tmp);

return *this;

}

~string()

{

delete[] _str;

_str = nullptr;

_size = _capacity = 0;

}

const char* c_str() const

{

return _str;

}

size_t size() const

{

return _size;

}

char& operator[](size_t pos)

{

assert(pos < _size);

return _str[pos];

}

const char& operator[](size_t pos) const

{

assert(pos < _size);

return _str[pos];

}

void reserve(size_t n)

{

//要加判断条件,因为当n <= _capacity时不做任何处理

if (n > _capacity)

{

char* tmp = new char[n + 1];

memcpy(tmp, _str, _size + 1);

delete[] _str;

_str = tmp;

_capacity = n;

}

}

void push_back(char ch)

{

if (_size == _capacity)

{

// 2倍扩容

reserve(_capacity == 0 ? 4 : _capacity * 2);

}

_str[_size] = ch;

++_size;

_str[_size] = '\0';

}

void append(const char* str)

{

size_t len = strlen(str);

if (_size + len > _capacity)

{

// 至少扩容到_size + len

reserve(_size + len);

}

memcpy(_str + _size, str, len + 1);

_size += len;

}

string& operator+=(char ch)//末尾添加字符

{

push_back(ch);

return *this;

}

string& operator+=(const char* str)//末尾添加字符串

{

append(str);

return *this;

}

void insert(size_t pos, size_t n, char ch)//从下标pos位置开始向后插入n个字符ch

{

assert(pos <= _size);

if (_size + n > _capacity)

{

// 至少扩容到_size + n

reserve(_size + n);

}

// 挪动数据

/*int end = _size;

while (end >= (int)pos)//整型提升有符号向无符号提升

{

_str[end + n] = _str[end];

--end;

}*/

// 挪动数据

size_t end = _size;

while (end >= pos && end != npos)

{

_str[end + n] = _str[end];

--end;

}

for (size_t i = 0; i < n; i++)

{

_str[pos + i] = ch;

}

_size += n;

}

void insert(size_t pos, const char* str)

{

assert(pos <= _size);

size_t len = strlen(str);

if (_size + len > _capacity)

{

// 至少扩容到_size + len

reserve(_size + len);

}

size_t end = _size;

while (end >= pos && end != npos)

{

_str[end + len] = _str[end];

--end;

}

for (size_t i = 0; i < len; i++)

{

_str[pos + i] = str[i];

}

_size += len;

}

void erase(size_t pos, size_t len = npos)

{

assert(pos <= _size);

if (len == npos || pos + len >= _size)//将pos后面的数据删完

{

_str[pos] = '\0';

_size = pos;

}

else//删除pos到结尾的部分连续数据

{

size_t end = pos + len;

while (end <= _size)

{

_str[pos++] = _str[end++];

}

_size -= len;

}

}

size_t find(char ch, size_t pos = 0)//找字符下标

{

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 = 0)//找字符串下标

{

assert(pos < _size);

const char* ptr = strstr(_str + pos, str);

if (ptr)

{

return ptr - _str;

}

else

{

return npos;

}

}

string substr(size_t pos = 0, size_t len = npos)

{

assert(pos < _size);

size_t n = len;

if (len == npos || pos + len > _size)

{

n = _size - pos;

}

string tmp;

tmp.reserve(n);

for (size_t i = pos; i < pos + n; i++)

{

tmp += _str[i];

}

return tmp;

}

//bool operator<(const string& s)

//{

//size_t i1 = 0;

//size_t i2 = 0;

//while (i1 < _size && i2 < s._size)

//{

//if (_str[i1] < s._str[i2])

//{

//return true;

//}

//else if (_str[i1] > s._str[i2])

//{

//return false;

//}

//else

//{

//++i1;

//++i2;

//}

//}

//// "hello" "hello" false

//// "helloxx" "hello" false

//// "hello" "helloxx" true

///*if (i1 == _size && i2 != s._size)

//{

//return true;

//}

//else

//{

//return false;

//}

//}

void clear()

{

_str[0] = '\0';

_size = 0;

}

bool operator<(const string& s) const

{

int ret = memcmp(_str, s._str, _size < s._size ? _size : s._size);

// "hello" "hello" false

// "helloxx" "hello" false

// "hello" "helloxx" true

return ret == 0 ? _size < s._size : ret < 0;

}

bool operator==(const string& s) const

{

return _size == s._size

&& memcmp(_str, s._str, _size) == 0;

}

bool operator<=(const string& s) const

{

return *this < s || *this == s;

}

bool operator>(const string& s) const

{

return !(*this <= s);

}

bool operator>=(const string& s) const

{

return !(*this < s);

}

bool operator!=(const string& s) const

{

return !(*this == s);

}

private:

size_t _size;

size_t _capacity;

char* _str;

public:

//const static size_t npos = -1; // 虽然可以这样用,但是不建议

const static size_t npos;

//const static double x = 1.1;//不支持除了int以外其他const static类型在类内定义并初始化

};

const size_t string::npos = -1;

//const double string::x = 1.1;

ostream& operator<<(ostream& out, const string& s)

{

/*for (size_t i = 0; i < s.size(); i++)

{

out << s[i];

}*/

for (auto ch : s)

{

out << ch;

}

return out;

}

istream& operator>>(istream& in, string& s)

{

s.clear();

char ch = in.get();

// 处理缓冲区前面的空格或者换行

while (ch == ' ' || ch == '\n')

{

ch = in.get();

}

//in >> ch;

char buff[128];

int i = 0;

while (ch != ' ' && ch != '\n')

{

buff[i++] = ch;

if (i == 127)

{

buff[i] = '\0';

s += buff;

i = 0;

}

//in >> ch;

ch = in.get();

}

if (i != 0)

{

buff[i] = '\0';

s += buff;

}

return in;

}

};

2. Text.cpp

#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>

#include<string>

using namespace std;

#include"string.h"

void test_string1()

{

wch::string s1("hello world");

cout << s1.c_str() << endl;

wch::string s2;

cout << s2.c_str() << endl;

for (size_t i = 0; i < s1.size(); i++)

{

s1[i]++;

}

for (size_t i = 0; i < s1.size(); i++)

{

cout << s1[i] << " ";

}

cout << endl;

const wch::string s3("hello world");

s3[0];

//wch::string::const_iterator cit = s3.begin();

auto cit = s3.begin();

while (cit != s3.end())

{

//*cit += 1;

cout << *cit << " ";

++cit;

}

cout << endl;

wch::string::iterator it = s1.begin();

while (it != s1.end())

{

*it += 1;

cout << *it << " ";

++it;

}

cout << endl;

for (auto ch : s1)

{

cout << ch << " ";

}

cout << endl;

}

void test_string2()

{

wch::string s1("hello world");

cout << s1.c_str() << endl;

s1.push_back(' ');

s1.push_back('#');

s1.append("hello world");

cout << s1.c_str() << endl;

wch::string s2("hello world");

cout << s2.c_str() << endl;

s2 += ' ';

s2 += '#';

s2 += "hello world";

cout << s2.c_str() << endl;

}

void test_string3()

{

wch::string s1("helloworld");

cout << s1.c_str() << endl;

s1.insert(5, 3, '#');

cout << s1.c_str() << endl;

s1.insert(0, 3, '#');

cout << s1.c_str() << endl;

wch::string s2("helloworld");

s2.insert(5, "%%%%%");

cout << s2.c_str() << endl;

}

void test_string4()

{

wch::string s1("helloworld");

cout << s1.c_str() << endl;

s1.erase(5, 3);

cout << s1.c_str() << endl;

s1.erase(5, 30);

cout << s1.c_str() << endl;

s1.erase(2);

cout << s1.c_str() << endl;

}

void test_string5()

{

// 2118

wch::string url = "ftp://www.baidu.com/?tn=65081411_1_oem_dg";

size_t pos1 = url.find("://");

cout << pos1 << endl;

if (pos1 != wch::string::npos)

{

wch::string protocol = url.substr(0, pos1);

cout << protocol.c_str() << endl;

}

size_t pos2 = url.find('/', pos1 + 3);

cout << pos2 << endl;

if (pos2 != wch::string::npos)

{

wch::string domain = url.substr(pos1 + 3, pos2 - (pos1 + 3));

wch::string uri = url.substr(pos2 + 1);

cout << domain.c_str() << endl;

cout << uri.c_str() << endl;

}

}

void test_string6()

{

wch::string s1("helloworld111");

wch::string s2("helloworld22222");

s1 = s2;

cout << s1;

}

void test_string7()

{

wch::string s1("abcd");

wch::string s2("abcd");

cout << (s1 > s2) << endl;

cout << (s1 < s2) << endl;

cout << (s1 == s2) << endl << endl;

wch::string s3("abcd");

wch::string s4("abcdxxx");

cout << (s3 > s4) << endl;

cout << (s3 < s4) << endl;

cout << (s3 == s4) << endl << endl;

wch::string s5("bb");

wch::string s6("abcd");

cout << (s5 > s6) << endl;

cout << (s5 < s6) << endl;

cout << (s5 == s6) << endl;

}

void test_string8()

{

wch::string s1("abcd");//向s1输入数据时,会先清s1原有数据;

wch::string s2;

cin >> s1;

cout << s1 << endl;

cin >> s2;

cout << s2;

}

int main()

{

//test_string1();

//test_string2();

//test_string3();

//test_string4();

//test_string5();

//test_string6();

//test_string7();

test_string8();

return 0;

}



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。