string的使用和模拟实现-2

简介: string的使用和模拟实现

运算符重载

  1. 赋值运算符

也就是说我们可以直接用string对象或者字符串来给新的对象赋值。

int main()
{
  string s;
  s = "123456";
  string s1("xxx");
  s = s1;
  return 0;
}
  1. +和+=

从这两张图我们就可以看出来,+=是成员函数,而+是全局函数。我们需要尾插是可以用+=也可以用+,但是+的代价是很大的,我们尽量使用+=。

int main()
{
  string  s("123");
  s += "456";
  s += '7';
  s = s + '8';
  return 0;
}

模拟实现

string& operator+=(const char s)
{
    push_back(s);
    return *this;
}
string& operator+=(const char* s)
{
    append(s);
    return *this;
}
  1. 流插入和流提取

也就是说,我们可以直接使用cout和cin来对sting对象来进行输入和输出了。


模拟实现

  1. 流提取
    我们可以一个字符一个字符的提取,因为_str为私有的,我们无法访问,我们也可以使用友元,但是我们这里一个字符一个字符的访问。
ostream& operator<<(ostream& out, const string& s)
{
    int end = s.size();
    for (int i = 0; i < end; i++)
    {
        out << s[i];
    }
    return out;
}


  1. 流插入

流插入也一样,我们一个字符一个字符的读,当读到‘\n’或者空格就停止,但是cin和scanf都无法读空格和换行,这是就需要一个函数,cin.get(),它的功能就和C语言的getcahr很相似。

istream& operator>>(istream& in, string& s)
{
    s.clear();
    char ch = in.get();
    while (ch != ' ' && ch != '\n')
    {
        s += ch;
        ch = in.get();
    }
    return in;
}
int main()
{
  string s;
  cin >> s;
  cout << s << endl;
  return 0;
}
  1. 比较运算符

    我们可以直接使用比较运算符来对sting对象和字符串等进行比较了。


模拟实现

char& operator[](size_t pos)
{
    assert(pos < _size);
    return _str[pos];
}
const char& operator[](size_t pos) const
{
    assert(pos < _size);
    return _str[pos];
}
string& operator+=(const char s)
{
    push_back(s);
    return *this;
}
string& operator+=(const char* s)
{
    append(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);
}


push_back和append

  1. push_back

尾插一个字符


  1. append

尾插一段字符串,库里面给的接口很多,我们都不是很常用,我们都喜欢用+=。


模拟实现

void push_back(const char ch)
{
    if (_size == _capacity)
    {
        reserve(_capacity == 0 ? 4 : _capacity * 2);
    }
    _str[_size++] = ch;
    _str[_size] = '\0';
}
void append(const char* s)
{
    size_t len = strlen(s);
    if (_size + len > _capacity)
    {
        reserve(_size+len);
    }
    strcpy(_str + _size, s);
    _size += len;
}


insert和erase

  1. insert

我们一般用的都是在某个位置插入一个字符或者字符串。


模拟实现

string& insert(size_t pos, char ch)
{
    assert(pos <= _size);
    if (_size == _capacity)
    {
        reserve(_capacity == 0 ? 4 : _capacity * 2);
    }
    int end = _size;
    //必须强转,不然会类型提升,当pos=0时发生死循环
    while (end >= (int)pos)
    {
        _str[end + 1] = _str[end];
        end--;
    }
    _str[pos] = ch;
    _size++;
    return *this;
}
string& insert(size_t pos, const char* str)
{
    size_t len = strlen(str);
    if (_size + len > _capacity)
    {
        reserve(_size + len);
    }
    int end = _size;
    while (end >= (int)pos)
    {
        _str[end + len] = _str[end];
        end--;
    }
    strncpy(_str + pos, str, len);
    _size += len;
    return *this;
}


  1. erase

删除某个位置的len个字符


模拟实现

earse我们需要提供一个npos的半缺省参数,如果不给的话就表示将pos以后得数据都删了。

nops是一个所有类都有的,所以我们可以定义为静态成员变量。

string& erase(size_t pos, size_t len = npos)
{
  assert(pos < _size);
   if (pos + len > _size || len == npos)
   {
       _str[pos] = '\0';
       _size = pos;
       return *this;
   }
   else
   {
       size_t begin = pos + len;
       while (begin <= _size)
       {
           _str[begin - len] = _str[begin];
           begin++;
       }
       _size -= len;
       return *this;
   }
}
public:
        const static int npos = -1;


查找

  1. find

    我们可以用这个函数来查找字符串或者字符。
int main()
{
  string s("123456");
  int i = s.find("23");
  int j = s.find('5',2);
  int x = s.find("123", 2, 3);
  return 0;
}


  1. rfind

    rfind也是查找只不过是从最后开始找。和find相似。

模拟实现

size_t find(char c, size_t pos = 0) const
 {
     assert(pos < _size);
     for (size_t i = pos; i < _size; i++)
     {
         if (_str[i] == c)
         {
             return i;
         }
     }
     return npos;
 }
 size_t find(const char* s, size_t pos = 0) const
 {
     size_t len = strlen(s);
     assert(pos + len < _size);
     char* str = strstr(_str + pos, s);
     if (str != nullptr)
     {
         return str - _str;
     }
     return npos;
 }


截取字符串

substr

从pos位置开始提取len个字符,不给len直接取到最后。

模拟实现

string substr(size_t pos = 0, size_t len = npos) const
{
    string s;
    if (len == npos || pos + len > _size)
    {
        size_t i = 0;
        for (i = pos; i <= _size; i++)
        {
            s += _str[i];
        }
        return s;
    }
    else
    {
        size_t i = 0;
        for (i = pos; i < pos+len; i++)
        {
            s += _str[i];
        }
        s += '\0';
        return s;
    }
}


获取字符指针

我们知道string是一个类,那我们想要得到底层的那个字符指针怎么获得呢?

我们可以使用c_str这个函数

int main()
{
  string s("123456");
  const char* str = s.c_str();
  return 0;
}

模拟实现

const char* c_str() const
{
    return _str;
}

交换对象

swap

对于string有一个专门的swap,可以用来交换两个string对象。

int main()
{
  string s("123456");
  string s1("12");
  s.swap(s1);
  cout << s << endl << s1 << endl;
  return 0;
}

模拟实现

void swap(string& s)
 {
     std::swap(_str, s._str);
     std::swap(_size, s._size);
     std::swap(_capacity, s._capacity);
 }

特殊读取

我们知道cin和scanf一样,遇到空格或者换行都会提前结束,那我们需要读取的字符串包含空格或者换行怎么办呢,这时候就需要getline了。

int main()
{
  string s;
  getline(cin, s);
  cout << s;
  return 0;
}

我们也可以自己指定读取结束的字符。

今天的分享就到这里,感谢大家的关注和支持。

相关文章
|
存储 C语言 C++
string的使用和模拟实现-1
string的使用和模拟实现
|
1月前
|
C++ 容器
|
1月前
|
C++ 容器
|
1月前
|
C++
|
4月前
|
编译器 程序员 C语言
【C++】string模拟实现
这篇博客探讨了自定义实现C++ `string` 类的关键功能,包括构造、拷贝构造、赋值运算符重载及析构函数。作者强调了理解并实现这些功能对于面试的重要性。博客介绍了`string` 类的头文件`string.h`,其中定义了迭代器、基本成员函数如`swap()`、`size()`、`c_str()`等,并提到了深拷贝概念。此外,还展示了构造函数、析构函数和赋值运算符的实现,以及迭代器的定义与使用。博客还包括对C语言字符串函数的引用,以辅助读者理解实现细节。
|
4月前
|
C语言 C++
【C++】string模拟实现(下)
本文档介绍了自定义`string`类的一些关键功能实现,包括`reserve()`用于内存管理,`push_back()`和`append()`添加字符或字符串,运算符`+=`的重载,以及`insert()`, `erase()`进行插入和删除操作。此外,还涵盖了`find()`查找函数,字符串的比较运算符重载,`substr()`获取子串,`clear()`清除内容,以及流插入和提取操作。常量`npos`用于表示未找到的标记。文档以代码示例和运行结果展示各功能的使用。
|
5月前
|
C语言 C++
【c++】string模拟实现(2)
【c++】string模拟实现(2)
24 0
|
5月前
|
算法 C++
【c++】string模拟实现(1)
【c++】string模拟实现(1)
132 0
|
6月前
|
存储 编译器 C++
【C++】——string的模拟实现
【C++】——string的模拟实现
|
6月前
|
Java 编译器 C++
string的模拟(上)
string的模拟
62 1