模拟实现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;
}
 


相关文章
|
20天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
30 2
|
2月前
|
Java
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
本文深入探讨了Java中方法参数的传递机制,包括值传递和引用传递的区别,以及String类对象的不可变性。通过详细讲解和示例代码,帮助读者理解参数传递的内部原理,并掌握在实际编程中正确处理参数传递的方法。关键词:Java, 方法参数传递, 值传递, 引用传递, String不可变性。
65 1
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
|
2月前
|
安全 Java 测试技术
Java零基础-StringBuffer 类详解
【10月更文挑战第9天】Java零基础教学篇,手把手实践教学!
45 2
|
2月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
25 1
|
2月前
|
数据可视化 Java
让星星月亮告诉你,通过反射创建类的实例对象,并通过Unsafe theUnsafe来修改实例对象的私有的String类型的成员属性的值
本文介绍了如何使用 Unsafe 类通过反射机制修改对象的私有属性值。主要包括: 1. 获取 Unsafe 的 theUnsafe 属性:通过反射获取 Unsafe类的私有静态属性theUnsafe,并放开其访问权限,以便后续操作 2. 利用反射创建 User 类的实例对象:通过反射创建User类的实例对象,并定义预期值 3. 利用反射获取实例对象的name属性并修改:通过反射获取 User类实例对象的私有属性name,使用 Unsafe`的compareAndSwapObject方法直接在内存地址上修改属性值 核心代码展示了详细的步骤和逻辑,确保了对私有属性的修改不受 JVM 访问权限的限制
60 4
|
2月前
|
存储 安全 Java
【一步一步了解Java系列】:认识String类
【一步一步了解Java系列】:认识String类
28 2
|
2月前
|
存储 编译器 程序员
【C++篇】手撕 C++ string 类:从零实现到深入剖析的模拟之路
【C++篇】手撕 C++ string 类:从零实现到深入剖析的模拟之路
73 2
|
2月前
|
C语言 C++
C++番外篇——string类的实现
C++番外篇——string类的实现
21 0
|
2月前
|
C++ 容器
C++入门7——string类的使用-2
C++入门7——string类的使用-2
22 0
|
2月前
|
C语言 C++ 容器
C++入门7——string类的使用-1
C++入门7——string类的使用-1
23 0