string.h
#pragma once
#include <iostream>
#include <assert.h>
namespace zyh
{
class string
{
public:
typedef char* iterator;
typedef const char* const_iterator;
public:
string(const char* str = "");
string(const string& s);
string& operator=(string s);
~string();
inline iterator begin()
{
return &_str[0];
}
inline const_iterator begin() const
{
return &_str[0];
}
inline iterator end()
{
return &_str[size()];
}
inline const_iterator end() const
{
return &_str[size()];
}
// modify
void push_back(char c = '\0');
void append(const char* str);
string& operator+=(char c);
string& operator+=(const char* str);
void swap(string& s);
string& insert(size_t pos, char c);
string& insert(size_t pos, const char* str);
string& erase(size_t pos, size_t len = npos);
// string operation
inline const char* c_str() const
{
return _str;
}
// 返回c在string中第一次出现的位置
size_t find(char c, size_t pos = 0) const;
// 返回子串s在string中第一次出现的位置
size_t find(const char* s, size_t pos = 0) const;
// capacity
inline size_t size() const
{
return _size;
}
inline size_t capacity() const
{
return _capacity;
}
inline bool empty() const
{
return _size == 0;
}
inline void clear()
{
_str[0] = '\0';
_size = 0;
}
void resize(size_t n, char c = '\0');
void reserve(size_t n = 0);
// access
inline char& operator[](size_t index)
{
assert(index < size());
return _str[index];
}
inline const char& operator[](size_t index) const
{
assert(index < size());
return _str[index];
}
//relational operators
inline bool operator<(const string& s)
{
return _size < s.size();
}
inline bool operator<=(const string& s)
{
return _size <= s.size();
}
inline bool operator>(const string& s)
{
return _size > s.size();
}
inline bool operator>=(const string& s)
{
return _size >= s.size();
}
inline bool operator==(const string& s)
{
return !strcmp(_str, s.c_str());
}
inline bool operator!=(const string& s)
{
return strcmp(_str, s.c_str());
}
private:
char* _str = nullptr;
size_t _size = 0;
size_t _capacity = 0;
static size_t npos;
};
std::ostream& operator<<(std::ostream& _cout, const string& s);
std::istream& operator>>(std::istream& _cin, string& s);
};
string.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include "string.h"
namespace zyh
{
size_t string::npos = -1;
string::string(const char* str)
{
_size = strlen(str);
_capacity = _size;
_str = new char[_size + 1];
strcpy(_str, str);
}
string::string(const string& s)
{
// 经典写法
//_size = _capacity = s.size();
//_str = new char[_size + 1];
//strcpy(_str, s.c_str());
// 现代写法
string tmp(s.c_str());
swap(tmp);
}
// 经典写法
//string::string& operator=(const string& s)
//{
// if (s.size() != _capacity)
// {
// char* str = new char[s.size() + 1];
// delete[] _str;
// _str = str;
// _size = s.size();
// _capacity = s.size();
// }
// strcpy(_str, s.c_str());
// return *this;
//}
// 现代写法
string& string::operator=(string s)
{
swap(s);
return *this;
}
string::~string()
{
_size = 0;
_capacity = 0;
delete[] _str;
_str = nullptr;
}
// modify
void string::push_back(char c)
{
if (_size == _capacity)
{
reserve(_capacity == 0 ? 4 : 2 * _capacity);
}
_str[_size++] = c;
_str[_size] = '\0';
}
void string::append(const char* str)
{
size_t len = strlen(str);
if (len + _size > _capacity)
{
reserve(len + _size);
}
strcpy(_str + _size, str);
_size += len;
}
string& string::operator+=(char c)
{
push_back(c);
return *this;
}
string& string::operator+=(const char* str)
{
append(str);
return *this;
}
void string::swap(string& s)
{
//char* tmp1 = s._str;
//s._str = _str;
//_str = tmp1;
//size_t tmp2 = s.size();
//s._size = _size;
//_size = tmp2;
//tmp2 = s.capacity();
//s._capacity = _capacity;
//_capacity = tmp2;
std::swap(_str, s._str);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);
}
string& string::insert(size_t pos, char c)
{
if (_size == _capacity)
{
reserve(_capacity == 0 ? 4 : 2 * _capacity);
}
size_t end = ++_size;
while (end > pos)
{
_str[end] = _str[end - 1];
--end;
}
_str[end] = c;
return *this;
}
string& string::insert(size_t pos, const char* str)
{
size_t len = strlen(str);
if (len + _size > _capacity)
{
reserve(len + _size);
}
int end = len + _size;
while (end >= (int)(pos + len))
{
_str[end] = _str[end - len];
--end;
}
strncpy(_str + pos, str, len);
_size += len;
return *this;
}
string& string::erase(size_t pos, size_t len)
{
if (len == npos || len >= _size - pos)
{
_size = pos;
_str[_size] = '\0';
}
else
{
size_t begin = pos;
while (begin <= _size - len)
{
_str[begin] = _str[begin + len];
++begin;
}
_size -= len;
}
return *this;
}
// string operation
// 返回c在string中第一次出现的位置
size_t string::find(char c, size_t pos) const
{
assert(pos < _size);
for (size_t i = pos; i < _size; ++i)
{
if (_str[i] == c)
return i;
}
return npos;
}
// 返回子串s在string中第一次出现的位置
size_t string::find(const char* s, size_t pos) const
{
assert(pos < _size);
if (char* retp = strstr(_str + pos, s))
return retp - _str;
return npos;
}
// capacity
void string::resize(size_t n, char c)
{
if (n < _size)
{
_size = n;
_str[n] = '\0';
}
else if (n > _size && n <= _capacity)
{
for (size_t begin = _size; begin < n; ++begin)
{
_str[begin] = c;
}
_size = n;
_str[n] = '\0';
}
else if (n > _capacity)
{
reserve(n);
for (size_t begin = _size; begin < n; ++begin)
{
_str[begin] = c;
}
_size = n;
_str[n] = '\0';
}
}
void string::reserve(size_t n)
{
if (n > _capacity)
{
char* str = new char[n + 1];
_capacity = n;
strcpy(str, _str);
delete[] _str;
_str = str;
}
}
std::ostream& operator<<(std::ostream& _cout, const string& s)
{
/*for (size_t i = 0; i < s.size(); ++i)
{
_cout << s.c_str()[i];
}*/
//_cout << s.c_str();
for (auto ch : s)
{
_cout << ch;
}
return _cout;
}
std::istream& operator>>(std::istream& _cin, string& s)
{
s.clear();
char buf[128];
buf[127] = '\0';
size_t i = 0;
char ch = _cin.get();
while (ch != ' ' && ch != '\n')
{
if (i == 127)
{
s += buf;
i = 0;
}
buf[i] = ch;
ch = _cin.get();
++i;
}
buf[i] = '\0';
s += buf;
return _cin;
}
};