您的位置:首页 > 编程语言 > C语言/C++

C++实现String类

2017-10-20 23:27 489 查看

头文件: my_string.h

#ifndef MY_STRING_H_
#define MY_STRING_H_
#pragma once

#include <iostream>

class MyString {
public:
MyString();
MyString(const char* c_str);
MyString(size_t n, char ch);
MyString(const MyString& str);
MyString(const MyString& str, size_t pos, size_t n = NPOS);

~MyString();

size_t len() const { return len_; }
size_t capacity() const { return capacity_; }
const char* c_str() const { return buf_; }

bool IsEmpty() const;
void Clear();

size_t Size() const;

void Resize(size_t n);
void Resize(size_t n, char ch);
void Reserve(size_t n = 0);

const char& At(size_t pos) const;
char& At(size_t pos);

MyString& Append(const MyString& my_str);
MyString& Append(const char* c_str);

MyString& Assign(const MyString& my_str);
MyString& Assign(const char* c_str);

MyString& Insert(size_t pos, const MyString& my_str);
MyString& Insert(size_t pos, const char* c_str);

MyString& Erase(size_t pos = 0, size_t n = NPOS);

int Compare(const MyString& my_str) const;
int Compare(const char* c_str) const;

MyString SubStr(size_t pos = 0, size_t n = NPOS) const;

bool StartWith(const char* c_str) const;
bool EndWith(const char* c_str) const;

size_t Find(const char* c_str, size_t pos = 0) const;
size_t Find(const MyString& my_str, size_t pos = 0) const;

MyString& Replace(size_t pos, size_t n, const char* c_str);
MyString& Replace(const char* src_str, const char* target_str);

friend std::istream& operator>>(std::istream& is, MyString& my_str);
friend std::ostream& operator<<(std::ostream& os, const MyString& my_str);

friend MyString operator+(const MyString& left_my_str, const MyString& right_my_str);
friend MyString operator+(const MyString& left_my_str, const char* right_c_str);
friend MyString operator+(const char* left_c_str, const MyString& right_my_str);

friend bool operator==(const MyString& left_my_str, const MyString& right_my_str);
friend bool operator!=(const MyString& left_my_str, const MyString& right_my_str);

friend bool operator<(const MyString& left_my_str, const MyString& right_my_str);
friend bool operator>(const MyString& left_my_str, const MyString& right_my_str);
friend bool operator>=(const MyString& left_my_str, const MyString& right_my_str);
friend bool operator<=(const MyString& left_my_str, const MyString& right_my_str);

MyString& operator=(const MyString& my_str);
MyString& operator=(const char* c_str);
MyString& operator=(char ch);

MyString& operator+=(const MyString& my_str);
MyString& operator+=(const char* c_str);

const char& operator[](size_t pos) const;

char& operator[](size_t pos);

public:
static const size_t NPOS;

private:
char* buf_;
size_t capacity_;
size_t len_;
};

#endif // MY_STRING_H_

源文件: my_string.cpp

#include "my_string.h"
#include <cassert>

const size_t kDefaultBufSize = 16;

const size_t MyString::NPOS = -1;

MyString::MyString() {
capacity_ = kDefaultBufSize;
buf_ = new char[capacity_ + 1];
buf_[0] = '\0';
len_ = 0;
}

MyString::MyString(size_t n, char ch) {
capacity_ = n + kDefaultBufSize;
buf_ = new char[capacity_ + 1];
len_ = n;
for (size_t i = 0; i < n; ++i) {
buf_[i] = ch;
}
buf_[len_] = '\0';
}

MyString::MyString(const char* c_str) {
size_t c_str_size = strlen(c_str);
capacity_ = c_str_size + kDefaultBufSize;
buf_ = new char[capacity_ + 1];
strcpy(buf_, c_str);
len_ = c_str_size;
}

MyString::MyString(const MyString& my_str) {
buf_ = new char[my_str.capacity_ + 1];
strcpy(buf_, my_str.buf_);
capacity_ = my_str.capacity_;
len_ = my_str.len_;
}

MyString::MyString(const MyString& my_str, size_t pos, size_t n) {
if (pos > len_) {
throw std::out_of_range("invalid string position");
}
if (pos + n > len_) {
n = my_str.len_ - pos;
}
size_t size = n + kDefaultBufSize;
buf_ = new char[size + 1];
len_ = n;
capacity_ = size;
for (size_t i = 0; i < n; ++i) {
buf_[i] = my_str.buf_[pos + i];
}
buf_[len_] = '\0';
}

MyString::~MyString() {
if (buf_ != NULL) {
delete[] buf_;
capacity_ = 0;
len_ = 0;
}
}

MyString& MyString::operator=(const MyString& my_str) {
return operator=(my_str.buf_);
}

MyString& MyString::operator=(const char* c_str) {
size_t size = strlen(c_str);
if (size <= capacity_) {
strcpy(buf_, c_str);
len_ = size;
} else {
char* temp = buf_;
size += kDefaultBufSize;
buf_ = new char[size + 1];
strcpy(buf_, c_str);
capacity_ = size;
len_ = size - kDefaultBufSize;
delete[] temp;
}
return *this;
}

MyString& MyString::operator=(char ch) {
buf_[0] = ch;
buf_[1] = '\0';
len_ = 1;
return *this;
}

MyString& MyString::operator+=(const MyString& my_str) {
return Append(my_str);
}

MyString& MyString::operator+=(const char* c_str) {
return Append(c_str);
}

const char& MyString::operator[](size_t pos) const {
assert(pos < len_);
return buf_[pos];
}

char& MyString::operator[](size_t pos) {
assert(pos < len_);
return buf_[pos];
}

std::ostream& operator<<(std::ostream& os, const MyString& my_str) {
os << my_str.buf_;
return os;
}

std::istream& operator>>(std::istream& is, MyString& my_str) {
const size_t kMaxTempSize = 10000;
char* temp = new char[kMaxTempSize];
is >> temp;
size_t size = strlen(temp);
if (size <= my_str.capacity_) {
strcpy(my_str.buf_, temp);
my_str.len_ = size;
} else {
char* temp2 = my_str.buf_;
size += kDefaultBufSize;
my_str.buf_ = new char[size + 1];
strcpy(my_str.buf_, temp);
my_str.capacity_ = size;
my_str.len_ = size - kDefaultBufSize;
delete[] temp2;
}
delete[] temp;
return is;
}

MyString operator+(const MyString& left_my_str, const MyString& right_my_str) {
return MyString(left_my_str).Append(right_my_str);
}

MyString operator+(const MyString& left_my_str, const char* right_c_str) {
return MyString(left_my_str).Append(right_c_str);
}

MyString operator+(const char* left_c_str, const MyString& right_my_str) {
return MyString(left_c_str).Append(right_my_str);
}

bool operator==(const MyString& left_my_str, const MyString& right_my_str) {
return strcmp(left_my_str.buf_, right_my_str.buf_) == 0;
}

bool operator!=(const MyString& left_my_str, const MyString& right_my_str) {
return strcmp(left_my_str.buf_, right_my_str.buf_) != 0;
}

bool operator<(const MyString& left_my_str, const MyString& right_my_str) {
return strcmp(left_my_str.buf_, right_my_str.buf_) == -1;
}

bool operator>(const MyString& left_my_str, const MyString& right_my_str) {
return strcmp(left_my_str.buf_, right_my_str.buf_) == 1;
}

bool operator>=(const MyString& left_my_str, const MyString& right_my_str) {
return strcmp(left_my_str.buf_, right_my_str.buf_) >= 0;
}

bool operator<=(const MyString& left_my_str, const MyString& right_my_str) {
return strcmp(left_my_str.buf_, right_my_str.buf_) <= 0;
}

bool MyString::IsEmpty() const{
return len_ == 0;
}

void MyString::Clear() {
buf_[0] = '\0';
len_ = 0;
}

size_t MyString::Size() const{
return len_;
}

void MyString::Resize(size_t n) {
if (n <= len_) {
buf_
= '\0';
len_ = n;
} else {
if (n <= capacity_) {
for (size_t i = len_; i < n; i++) {
buf_[i] = ' ';
}
buf_
= '\0';
len_ = n;
} else {
size_t size = n + kDefaultBufSize;
char* temp = buf_;
buf_ = new char[size + 1];
strcpy(buf_, temp);
for (size_t i = len_; i < n; i++) {
buf_[i] = ' ';
}
delete[] temp;
buf_
= '\0';
len_ = n;
capacity_ = size;
}
}
}

void MyString::Resize(size_t n, char ch) {
if (n > len_) {
if (n <= capacity_) {
for (size_t i = len_; i < n; i++) {
buf_[i] = ch;
}
buf_
= '\0';
len_ = n;
} else {
size_t size = n + kDefaultBufSize;
char* temp = buf_;
buf_ = new char[size + 1];
strcpy(buf_, temp);
for (size_t i = len_; i < n; i++) {
buf_[i] = ch;
}
buf_
= '\0';
len_ = n;
capacity_ = size;
delete[] temp;
}
}
}

void MyString::Reserve(size_t n) {
if (n > capacity_) {
size_t size = n + kDefaultBufSize;
char* temp = buf_;
buf_ = new char[size + 1];
strcpy(buf_, temp);
capacity_ = size;
delete[] temp;
} else {
if (n > len_) {
char* temp = buf_;
buf_ = new char
;
strcpy(buf_, temp);
capacity_ = n;
delete[] temp;
}
}
}

const char& MyString::At(size_t pos) const {
if (pos < len_) {
return buf_[pos];
} else {
throw std::out_of_range("invalid string position");
}
}

char& MyString::At(size_t pos) {
if (pos < len_) {
return buf_[pos];
} else {
throw std::out_of_range("invalid string position");
}
}

MyString& MyString::Append(const MyString& my_str) {
return Append(my_str.buf_);
}

MyString& MyString::Append(const char* c_str) {
size_t size = len_ + strlen(c_str);
if (size <= capacity_) {
strcat(buf_, c_str);
len_ = size;
} else {
char* temp = buf_;
buf_ = new char[size + kDefaultBufSize + 1];
strcpy(buf_, temp);
strcat(buf_, c_str);
capacity_ = size + kDefaultBufSize;
len_ = size;
delete[] temp;
}
return *this;
}

MyString& MyString::Assign(const MyString& my_str) {
return operator=(my_str);
}

MyString& MyString::Assign(const char* c_str) {
return operator=(c_str);
}

MyString& MyString::Insert(size_t pos, const MyString& my_str) {
return Insert(pos, my_str.buf_);
}

MyString& MyString::Insert(size_t pos, const char* c_str) {
if (pos > len_) {
throw std::out_of_range("invalid string position");
}
size_t c_str_size = strlen(c_str);
size_t size = c_str_size + len_;
if (size <= capacity_) {
for (size_t i = size - 1; i >= pos + c_str_size; --i) {
buf_[i] = buf_[i - c_str_size];
}
for (size_t i = 0; i < c_str_size; ++i) {
buf_[i + pos] = c_str[i];
}
buf_[size] = '\0';
len_ = size;
} else {
char* temp = buf_;
buf_ = new char[size + kDefaultBufSize + 1];
for (size_t i = 0; i < pos; ++i) {
buf_[i] = temp[i];
}
for (size_t i = pos; i < pos + c_str_size; ++i) {
buf_[i] = c_str[i - pos];
}
for (size_t i = pos + c_str_size; i < size; ++i) {
buf_[i] = temp[i - c_str_size];
}
buf_[size] = '\0';
len_ = size;
capacity_ = size + kDefaultBufSize;
delete[] temp;
}
return *this;
}

MyString& MyString::Erase(size_t pos, size_t n) {
if (pos > len_) {
throw std::out_of_range("invalid string position");
}
if (pos + n > len_) {
buf_[pos] = '\0';
} else {
for (size_t i = 0; i < len_ - pos - n; ++i) {
buf_[pos + i] = buf_[pos + i + n];
}
buf_[len_ - n] = '\0';
len_ = len_ - n;
}
return *this;
}

int MyString::Compare(const char* c_str) const {
return strcmp(buf_, c_str);
}

int MyString::Compare(const MyString& my_str) const {
return Compare(my_str.buf_);
}

MyString MyString::SubStr(size_t pos, size_t n) const {
return MyString(*this, pos, n);
}

bool MyString::StartWith(const char* c_str) const {
if (c_str == NULL) {
return false;
}
return strncmp(c_str, buf_, strlen(c_str)) == 0;
}

bool MyString::EndWith(const char* c_str) const {
if (c_str == NULL) {
return false;
}
size_t end_size = strlen(c_str);
if (len_ < end_size) {
return false;
}
return strcmp(buf_ + len_ - end_size, c_str) == 0;
}

size_t MyString::Find(const char* c_str, size_t pos) const {
if (pos > len_) {
return NPOS;
}
size_t sub_str_size = strlen(c_str);
for (size_t i = pos; sub_str_size + i <= len_; ++i) {
if (strncmp(buf_ + i, c_str, sub_str_size) == 0) {
return i;
}
}
return NPOS;
}
size_t MyString::Find(const MyString& my_str, size_t pos) const {
return Find(my_str.buf_, pos);
}

MyString& MyString::Replace(size_t pos, size_t n, const char* dst_str) {
if (pos > len_) {
throw std::out_of_range("invalid string position");
}
if (pos + n > len_) {
n = len_ - pos;
}
size_t dst_str_size = strlen(dst_str);
size_t size = dst_str_size + len_ - n;
if (size > capacity_) {
char* temp = buf_;
buf_ = new char[size + kDefaultBufSize + 1];
strcpy(buf_, temp);
delete[] temp;
capacity_ = size;
}
char* temp = new char[len_ - n + 1];
strcpy(temp, buf_ + pos + n);
strcpy(buf_ + pos, dst_str);
strcpy(buf_ + pos + dst_str_size, temp);
len_ = len_ + dst_str_size - n;
delete[] temp;
return *this;

}

MyString& MyString::Replace(const char* src_str, const char* dst_str) {
size_t pos = Find(src_str);
if (pos == NPOS) {
return *this;
}
size_t n = strlen(src_str);
return Replace(pos, n, dst_str);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ string