还会慢慢测试找bug的
#pragma once
#include <cassert>
namespace YCB
{
class string
{
public:
typedef char* iterator;
static size_t npos;
iterator begin(){
return _str;
}
iterator end(){
return (_str+_size);
}
//构造
string(const char* s = "")
:_str(new char[strlen(s) + 1]),
_size(0),
_capacity(0)
{
strcpy(_str, s);
_size = _capacity = strlen(s);
}
//拷贝构造(传统版本) s2(s1)
/*string(const string& s)
:_str(new char[strlen(s._str)+1]) ///如果resize()加载了一大堆'\0',后面的'\0'不用他
{
strcpy(_str, s._str);///把'\0'也拷贝过来
}*/
//拷贝构造(现代版本)
string(const string& s)
:_str(nullptr)
{
string tmp(s);
swap(_str,tmp._str);
swap(_size,tmp._size);
swap(_capacity,tmp._capacity);
}
//赋值(传统版本) s3=s2
// s2.resize(1e7); 全'\0' s3空间正常开
//string& operator=(const string& s) {
// if (this != &s) {
// reserve(strlen(s._str));//申请开空间
// _size = s._size;
// }
//}
//赋值(现代版本1)
//string& operator=(const string& s) {
// string tmp(s);
// swap(_str, tmp._str);
// swap(_size, tmp._size);
// swap(_capacity, tmp._capacity);
// return *this;
//}
//赋值(现代版本2)
string& operator=(string s){
swap(_str, s._str);
swap(_size, s._size);
swap(_capacity, s._capacity);
return *this;
}
void push_back(char c){
if (_size == _capacity) {
size_t len = _capacity == 0 ? 2 : _capacity * 2;
reserve(len);
}
_str[_size++] = c;
_str[_size] = '\0';
}
string& append(const string& s){
size_t len = strlen(s._str);
if (s._size + len > s._capacity)
{
reserve(_size + len);
}
strcpy(end(), s._str);//0已经拷贝过来了
_size += len;
return *this;
}
//reserve
void reserve(size_t n){
if (n < _capacity) return; //空间足够时不开辟
char* tmp = new char[n + 1]; //多的1是给'\0'
if (!tmp) perror("reserve");
strcpy(tmp,_str);
delete[] _str;
_str = tmp;
_capacity = n;
}
void insert(size_t pos, char ch) {
if (_capacity == _size )
{
reserve(_capacity + 1);
}
memmove( _str+pos + 1, _str+pos, (_size - pos + 1 )*sizeof(char)); //注意把'/0'拷过去
}
string& insert(size_t pos, const char* s){
size_t len = strlen(s);
if (_capacity < _size + len)
{
reserve(_size + len);
}
memmove(_str + pos + len, _str + pos, (_size - pos + 1) * sizeof(char));//注意拷贝'\0'
for (int i = 0, j = pos; i < len; i++ , j++){
_str[j] = s[i];
}
_size += len;
return *this;
}
// If n is smaller than the current string length, the current value is shortened to its first n character, removing the characters beyond the nth.
void resize(size_t n, char c='\0') {
if (n < _size) {
_str[n] = '\0';
_size = n;
}
else {
if (n > _capacity) reserve(n);
int add = n - _size;
for (int i = 0; i < add; i++) push_back(c);
}
}
string& erase(size_t pos = 0, size_t len = npos) {
if ( pos + len >= _size) {
_size = 0;
_str[_size] = '\0';
}
else {
memmove( _str+pos, _str+pos + len, (_size -(pos+len) + 1 )*sizeof(char)); //把'\0'也拷贝过来
}
}
size_t find(char c, size_t pos = 0) {
for (int i = pos; i < _size; i++) {
if (c == _str[i]) {
return i;
}
}
return npos;
}
///kmp在实现了vector之后再更新
size_t find(const char* s, size_t pos = 0) {
int j = 0; size_t ed = strlen(s);
for (int i = pos; i < _size; i++) {
if (s[j] == _str[i]) {
j++;
if (j > ed) return i;
}
else j = 0;
}
return npos;
}
string& operator+=(const string& s) {
append(s);
return *this;
}
string& operator+=(const char ch) {
push_back(ch);
return *this;
}
string& operator+= (const char* s) {
insert(_size, s);
return *this;
}
bool operator>(const string& s){
return strcmp(_str,s._str) > 0;
}
bool operator==(const string& s) {
return strcmp(_str, s._str) == 0;
}
bool operator>=(const string& s) {
return (*this > s) || (*this == s);
}
bool operator<(const string& s) {
return !(*this >= s);
}
bool operator<=(const string& s) {
return !(*this > s);
}
bool operator!=(const string& s) {
return !(*this == s);
}
void clear() {
_size = 0;
_str[_size] = '\0';
}
size_t size() const {
return _size;
}
size_t capacity() const {
return _capacity;
}
char& front() const {
return _str[0];
}
char& back() const {
assert(_size > 0);
return _str[_size - 1];
}
char* c_str(){
return _str;
}
char& operator[](size_t pos) const {
assert(pos < _size);
return _str[pos];
}
bool empty() const {
if (_size == 0) return true;
return false;
}
//析构
~string() {
delete[] _str;
_str = nullptr;
_size = _capacity = 0;
}
private:
char* _str;
size_t _size;///已经用的有效字符
size_t _capacity;//有效字符的空间大小
};
size_t string:: npos = -1;
istream& operator>>(istream& in, string& s) {
s.clear();
while (1) {
char ch;
in.get(ch);
if (ch == ' ' || ch == '\n')
{
break;
}
s += ch;
}
return in;
}
istream& getline(istream& in, string& s) {
s.clear();
while (1) {
char ch;
in.get(ch);
if (ch == '\n')
{
break;
}
s += ch;
}
return in;
}
ostream& operator<<(ostream& out, const string& s) {
for (int i = 0; i < s.size(); i++) {
out << s[i];
}
return out;
}
}
测试文件
void test_string1()
{
string s1;
string s2("hello");
cout << s1 << endl;
cout << s2 << endl;
cout << s1.c_str() << endl;
cout << s2.c_str() << endl;
///三种遍历方式
for (size_t i = 0; i < s2.size(); i++)
{
s2[i] += 1;
cout << s2[i] << " ";
}cout << endl;
string::iterator it2 = s2.begin();//s2.Begin()就不行,因为没得替换
while (it2 != s2.end())
{
*it2 -= 1;
cout << *it2 << " ";
++it2;
}cout << endl;
//支持iterator begin end就可以
for (auto e : s2)///范围for会被编译器替换成迭代器
{
cout << e << " ";
}
cout << endl;
}
void test_string2()
{
string s1("hello");
s1.push_back(' ');
s1.push_back('w');
s1.push_back('o');
s1.append(" xxxxxxxxxxxxxxxxxx");
cout << s1 << endl;
string s2;
s2 += "hello";
s2 += " ";
s2 += "world";
cout << s2 << endl;
}
void test_string3()
{
string s1("hello");
s1.insert(1, "xy");
s1.insert(1, "xyz");
cout << s1 << endl;
}
void test_string4()
{
string s2("hello");
s2.reserve(10);
cout << s2 << endl;
cout << s2.size() << endl;
cout << s2.capacity() << endl;
s2.resize(8, 'x');
cout << s2.size() << endl;
cout << s2.capacity() << endl;
s2.resize(18, 'z');
cout << s2.size() << endl;
cout << s2.capacity() << endl;
s2.resize(2);
cout << s2.size() << endl;
cout << s2.capacity() << endl;
}
void test_string5() {
string s;
cin >> s;
cout << s << endl;
}
void test_string6() {
string s2("hello world");
s2.resize(20, 'x');
s2 += "!!!";
cout << s2 << endl;
cout << s2.c_str() << endl;
}