模拟实现string类--重载输入输出流

简介: 模拟实现string类--重载输入输出流

string.h

声明了一个空间域用来声明string类,这是为了避免和std标准命名空间里的string冲突

#define _CRT_SECURE_NO_WARNINGS 1
#include<assert.h>
#include<stdio.h>
#include<iostream>
#include<string.h>
namespace bit
 
{
 
  class string
 
  {
 
  public:
 
    typedef char* iterator;
    typedef const char* const_iterator;
 
  public:
 
    string(const char* str = "");
 
    string(const string& s);
 
    string& operator=(const string& s);
 
    ~string();
 
 
 
      //
 
      // iterator
 
    iterator begin();
 
    iterator end();
 
    const iterator begin()const;
 
    const iterator end() const;
 
 
      /
 
      // modify
 
    void push_back(char c);
 
    string& operator+=(char c);
 
    void append(const char* str);
 
    string& operator+=(const char* str);
 
    void clear();
 
    void swap(string& s);
 
    const char* c_str()const;
 
 
 
    /
 
    // capacity
 
    size_t size()const;
 
    size_t capacity()const;
 
    bool empty()const;
 
    void resize(size_t n, char c = '\0');
 
    void reserve(size_t n);
 
 
 
    /
 
    // access
 
    char& operator[](size_t index);
 
    const char& operator[](size_t index)const;
 
 
 
    /
 
    //relational operators
 
    bool operator<(const string& s);
 
    bool operator<=(const string& s);
 
    bool operator>(const string& s);
 
    bool operator>=(const string& s);
 
    bool operator==(const string& s);
 
    bool operator!=(const string& s);
 
 
 
    // 返回c在string中第一次出现的位置
 
    int find(char c, size_t pos = 0) const;
 
    // 返回子串s在string中第一次出现的位置
 
    int find(const char* s, size_t pos = 0) const;
 
    // 在pos位置上插入字符c/字符串str,并返回该字符的位置
 
    string& insert(size_t pos, char c);
 
    string& insert(size_t pos, const char* str);
 
 
 
    // 删除pos位置上的元素,并返回该元素的下一个位置
 
    string& erase(size_t pos, size_t len);
 
  private:
 
    char* _str;
 
    size_t _capacity;
 
    size_t _size;
 
  };
  std::ostream& operator<<(std::ostream& _cout, const bit::string& s);
  std::istream& operator>>(std::istream& _cin, bit::string& s);
  std::istream& getline(std::istream& _cin, bit::string& s);
};

string.cpp

定义string类中的函数声明以及操作符重载,其中输入输出流的重载是容易搞错的地方

#define _CRT_SECURE_NO_WARNINGS 1
#include"string.h"
 
bit::string::string(const char* str) :_size(strlen(str)){
  _str = new char[_size+1];
  strcpy(_str, str);
  _capacity = _size;
}
 
bit::string::string(const string& s) {
  _str = new char[s._capacity + 1];
  strcpy(_str, s._str);
  _size = s._size;
  _capacity = s._capacity;
}
 
bit::string& bit::string::operator=(const string& s) {
  char* temp = new char[s._capacity+1];
  strcpy(temp, s._str);
 
  delete[] _str;
  _capacity = s._capacity;
  _size = s._size;
  _str = temp;
  return *this;
}
 
bit::string::~string() {
  delete[] _str;
  _capacity = 0;
  _size = 0;
}
 
// iterator
//迭代器
bit::string::iterator bit::string::begin() {
  return _str;
}
bit::string::iterator bit::string::end() {
  return _str + _size;
}
 
const bit::string::iterator bit::string::begin()const {
  return _str;
}
const bit::string::iterator bit::string::end() const{
  return _str + _size;
}
 
 
/
 
// 增加字符函数
 
void bit::string::push_back(char c) {
  if (_size == _capacity) {
    reserve(_capacity ==0?4:_capacity*2);
  }
  _str[_size++] = c;
  _str[_size] = '\0';
}
 
bit::string& bit::string::operator+=(char c) {
  (*this).push_back(c);
  return *this;
}
 
void bit::string::append(const char* str) {
  size_t n = strlen(str);
  for (int i = 0; i < n; i++)(*this).push_back(str[i]);
}
 
bit::string& bit::string::operator+=(const char* str) {
  append(str);
  return *(this);
}
 
void bit::string::clear() {
  _size = 0;
  _str[_size] = '\0';
}
 
void bit::string::swap(bit::string& s) {
  std::swap(s._str, _str);
  std::swap(s._size, _size);
  std::swap(s._capacity, _capacity);
}
 
const char* bit::string::c_str()const {
  return _str;
}
 
 
 
/
 
// capacity
//容量修改有关函数重载
size_t bit::string::size()const {
  return _size;
}
 
size_t bit::string::capacity()const {
  return _capacity;
}
 
bool bit::string::empty()const {
  return _size == 0;
}
 
void bit::string::resize(size_t n, char c ) {
  if (n <=_size) {
    _str[n] = '\0';
    _size = n;
  }
  else {
    reserve(n);
    for (size_t i = _size; i < n; i++) {
      _str[i] = c;
    }
    _str[n] = '\0';
    _capacity = n;
    _size = n;
  }
}
 
void bit::string::reserve(size_t n) {
  if (n > _capacity) {
    char* temp = new char[n + 1];
    strcpy(temp, _str);
    
    delete[] _str;
    _str = temp;
    _str[_size] = '\0';
    _capacity = n;
  }
}
 
// access
//下标访问
 
char& bit::string::operator[](size_t index) {
  assert(index >= 0 && index < _size);
  return _str[index];
}
 
const char& bit::string::operator[](size_t index)const {
  assert(index >= 0 && index < _size);
  return _str[index];
}
 
 
//relational operators
//比较操作符重载
 
bool bit::string::operator<(const bit::string& s) {
  int f = strcmp(_str, s._str);
  return f< 0;
}
bool bit::string::operator<=(const bit::string& s) {
  int f = strcmp(_str, s._str);
  return f <= 0;
}
 
bool bit::string::operator>(const bit::string& s) {
  int f = strcmp(_str, s._str);
  return f >0 ;
}
 
 
bool bit::string::operator>=(const bit::string& s) {
  int f = strcmp(_str, s._str);
  return f >= 0;
}
 
bool bit::string::operator==(const bit::string& s) {
  int f = strcmp(_str, s._str);
  return f == 0;
}
 
 
bool bit::string::operator!=(const bit::string& s) {
  int f = strcmp(_str, s._str);
  return f != 0;
}
 
 
// 返回c在string中第一次出现的位置
 
int  bit::string::find(char c, size_t pos ) const {
  assert(pos >= 0 && pos < _size);
  for (size_t i = pos; i < _size; i++) {
    if (_str[i] == c)return i;
  }
  return -1;
}
 
// 返回子串s在string中第一次出现的位置
 
int bit::string::find(const char* s, size_t pos ) const {
  assert(pos >= 0 && pos < _size);
  const char* t= strstr(_str + pos, s);
  if (t == NULL)return -1;
  return t - _str;
}
 
// 在pos位置上插入字符c/字符串str,并返回该字符的位置
 
bit::string& bit::string::insert(size_t pos, char c) {
  assert(pos <=_size);
  reserve(_capacity + 1);
  //_str[_size] = '\0';
  size_t end = _size+1;
  while (end >= pos) {
    _str[end] = _str[end-1];
    end--;
  }
  _str[pos] = c;
  _size++;
  return *this;
}
//
bit::string & bit::string::insert(size_t pos, const char* str) {
  assert(pos <= _size);
  size_t len = strlen(str);
  reserve(_capacity + len);
  size_t end = _size + len;
  while (end >= pos+len) {
    _str[end] = _str[end - len];
    end--;
  }
  strncpy(_str + pos, str, len);
  //size_t cnt = 0;
  /*for (size_t i = pos; i < pos + len; i++) {
    _str[i] = str[cnt++];
  }*/
  _size += len;
  _str[_size] = '\0';
  return *this;
}
//
//
//
 删除pos位置上的元素,并返回该元素的下一个位置
//
bit::string& bit::string::erase(size_t pos, size_t len) {
  assert(pos < _size);
  if (len >= _size - pos)len = _size - pos;
  size_t t = pos + len;
  strncpy(_str + pos, _str + t,len);
  _size--;
  _str[_size] = '\0';
  return *this;
}
 
std::ostream& bit::operator<<(std::ostream& _cout, const bit::string& s) {
  for (auto it : s) {
    _cout << it;
  }
  return _cout;
}
 
//std::istream& bit::operator>>(std::istream& _cin, bit::string& s) {
//  s.clear();
//  char ch;
//  ch = _cin.get();
//  s.reserve(128);
//  while (ch != '\n' && ch != ' ') {
//    s += ch;
//    ch = _cin.get();
//  }
//  return _cin;
//}
std::istream& bit::operator>>(std::istream& _cin, bit::string& s) {
  s.clear();
  char ch;
  ch = _cin.get();
  char buff[128];
  size_t cnt = 0;
  while (ch != '\n' && ch != ' ') {
    buff[cnt++] = ch;
    if (cnt == 127) {
      s += buff;
      cnt = 0;
    }
    ch = _cin.get();
  }
  if (cnt != 0) {
    buff[cnt] = '\0';
    s += buff;
    //s[(s.size())] = '\0';
    cnt = 0;
  }
  
  return _cin;
}
 
std::istream& bit::getline(std::istream& _cin, bit::string& s) {
  s.clear();
  char ch;
  ch = _cin.get();
  char buff[128];
  size_t cnt = 0;
  while (ch != '\n' ) {
    buff[cnt++] = ch;
    if (cnt == 127) {
      s += buff;
      cnt = 0;
    }
    ch = _cin.get();
  }
  if (cnt != 0) {
    buff[cnt] = '\0';
    s += buff;
    //s[(s.size())] = '\0';
    cnt = 0;
  }
 
  return _cin;
}
 


相关文章
|
19天前
|
Java 编译器 ice
【Java开发指南 | 第十五篇】Java Character 类、String 类
【Java开发指南 | 第十五篇】Java Character 类、String 类
31 1
|
19天前
|
C语言 C++
【C++】string类(常用接口)
【C++】string类(常用接口)
21 1
|
1天前
|
Java 安全 索引
滚雪球学Java(48):面向对象编程中的StringBuffer类详解
【6月更文挑战第2天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
23 5
滚雪球学Java(48):面向对象编程中的StringBuffer类详解
|
2天前
|
存储 Java 测试技术
滚雪球学Java(47):String类教程:如何在Java中使用字符串操作
【6月更文挑战第1天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
13 2
滚雪球学Java(47):String类教程:如何在Java中使用字符串操作
|
6天前
|
缓存 安全 Java
初识String类
初识String类
|
11天前
|
存储 Java API
【JAVA学习之路 | 提高篇】[内部类与常见API]String类
【JAVA学习之路 | 提高篇】[内部类与常见API]String类
|
11天前
|
Java API
【JAVA学习之路 | 提高篇】包装类(包装类与基本数据类型及String类之间的转换)
【JAVA学习之路 | 提高篇】包装类(包装类与基本数据类型及String类之间的转换)
|
13天前
|
编译器 测试技术 C语言
从C语言到C++_11(string类的常用函数)力扣58和415(下)
从C语言到C++_11(string类的常用函数)力扣58和415
8 0
|
13天前
|
存储 编译器 C语言
从C语言到C++_11(string类的常用函数)力扣58和415(中)
从C语言到C++_11(string类的常用函数)力扣58和415
12 0
|
13天前
|
存储 C语言 C++
从C语言到C++_11(string类的常用函数)力扣58和415(上)
从C语言到C++_11(string类的常用函数)力扣58和415
12 0