一级目录:string类的介绍
1.我们已经在c语言中学习了关于字符串函数的许多重要函数例如:strcpy(字符串拷贝函数),strcmp(字符串比较函数)等等可以实现我们想要的操作,但是在C++中,我们为了实现面向对象的思想,并且底层空间让用户自己保管,用c语言中的库函数有可能出现越界访问的存在。 2.经过我的简单介绍,我们来看看文档中对string类的介绍吧:
- 字符串是表示字符序列的类
- 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作
单字节字符字符串的设计特性。 - string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信
息,请参阅basic_string)。 - string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits
和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。 - 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个
类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。
二级目录:string类使用的重要函数接口及功能
1.首先,我们在使用string类中的函数时,必须先引进头文件
#include<string>
2.string类对象的常见构造如下
string()
string(const char* s)
string(size_t n,char c)
string(const string& s)
3.string类容量的基本操作函数接口:
size()
length()
capacity()
empty()
clear()
reserve(size_t n = 0)
resize(size_t n)
resize(size_t n,char c)
其中: ①.size和length的用法是相同的,一般为了与其他容器接口相同,我们一般使用的是size. ②.clear是清理字符串中的有效字符,与底层的空间容量无关。 ③.resize函数在进行扩容时,底层空间容量可能会改变,但是缩小不会改变。 ④.reserve函数,它不会改变已存在有效元素的个数,当reserve的参数小于 string的底层空间总大小时,reserver不会改变容量大小。
4.string类对象的访问及遍历操作函数接口:
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
iterator begin();
iterator end();
5.string类对象的修改操作函数接口:
void push_back (char c)
void push_front(char c)
string& append (const string& str);
string& operator+= (const string& str);
const char* c_str() const;
size_t find (const string& str, size_t pos = 0) const;
size_t rfind (const string& str, size_t pos = npos) const;
string substr (size_t pos = 0, size_t len = npos) const;
6.string类非成员函数
string operator+ (const string& lhs, const string& rhs);
istream& operator<< (istream& is, string& str);
istream& operator>> (istream& is, string& str);
istream& getline (istream& is, string& str);
三级目录:string类的模拟实现
#include<iostream>
using namespace std;
namespace My_string
{
class string
{
public:
typedef char* iterator;
friend ostream& operator<<(ostream& _cout, const My_string::string& s);
friend istream& operator>>(istream& _cin, My_string::string& s);
public:
string(const char* str = "")
{
m_capacity = m_size = strlen(str);
m_str = new char[m_capacity + 1];
strcpy(m_str, str);
}
string(const string &str) :m_str(nullptr), m_capacity(0), m_size(0)
{
string str_tmp(str.m_str);
this->Swap(str_tmp);
}
string& operator=(string str)
{
this->Swap(str);
return *this;
}
~string()
{
if (m_str)
{
m_capacity = m_size = 0;
delete[] m_str;
m_str = nullptr;
}
}
public:
iterator begin()
{
return (iterator)m_str;
}
iterator end()
{
return (iterator)m_str[m_size];
}
public:
void push_back(char c)
{
if (m_size == m_capacity)
{
reserve(2 * m_capacity + 1);
}
m_str[m_size++] = c;
m_str[m_size] = '\0';
}
string& operator+=(char c)
{
push_back(c);
return *this;
}
void append(const char* str)
{
size_t len = strlen(str);
while(len + m_size > m_capacity)
reserve(2 * m_capacity + 1);
strcpy(m_str+m_size, str);
m_size += len;
}
string& operator+=(const char* str)
{
append(str);
return *this;
}
void clear()
{
m_size = 0;
m_str[m_size] = '\0';
}
const char* c_str()const
{
return m_str;
}
public:
size_t size()
{
return m_size;
}
size_t capacity()
{
return m_capacity;
}
bool empty()
{
return m_size == 0;
}
void resize(size_t newSize, char c = '\0')
{
if (newSize > m_size)
{
if (newSize > m_capacity)
{
reserve(newSize);
}
memset(m_str +m_size, c, newSize - m_size);
}
m_size = newSize;
m_str[newSize] = '\0';
}
void reserve(size_t New_capacity)
{
if (New_capacity > m_capacity)
{
char* str = new char[New_capacity];
strcpy(str, m_str);
delete[] m_str;
m_str = str;
m_capacity = New_capacity;
}
}
public:
char& operator[](size_t index)
{
if (index < m_size)
return m_str[index];
}
const char& operator[](size_t index)const
{
if (index < m_size)
return m_str[index];
}
bool operator<(const string& s)
{
return strcmp(m_str, s.m_str) > 0;
}
bool operator<=(const string& s)
{
return strcmp(m_str, s.m_str) <= 0;
}
bool operator>(const string& s)
{
return strcmp(m_str, s.m_str) > 0;
}
bool operator>=(const string& s)
{
return strcmp(m_str, s.m_str) >= 0;
}
bool operator==(const string& s)
{
return strcmp(m_str, s.m_str) == 0;
}
bool operator!=(const string& s)
{
return strcmp(m_str, s.m_str) != 0;
}
size_t find(char c, size_t pos = 0) const
{
for (int i = pos; i < m_size; ++i)
{
if (m_str[i] == c)
return i;
}
return -1;
}
size_t find(const char* s, size_t pos = 0) const
{
for (int i = 0; i < m_size; ++i)
{
if (m_str[i] == s[0])
{
int count = i;
int j = 0;
for (; j < strlen(s) && count < m_size; ++j,++count)
{
if (m_str[count] != s[j])
break;
}
if (j == strlen(s))
return i;
}
}
return -1;
}
string& insert(size_t pos, char c)
{
if (m_size + 1 > m_capacity)
{
reserve(2 * m_capacity + 1);
}
for (int i = m_size - 1; i >= pos; --i)
{
m_str[i+1] = m_str[i];
}
m_str[pos] = c;
m_size++;
m_str[m_size] = '\0';
return *this;
}
string& insert(size_t pos, const char* str)
{
int len = strlen(str);
while (m_size + len > m_capacity)
{
reserve(2 * m_capacity + 1);
}
for (int i = m_size - 1; i >= pos; --i)
m_str[i+3] = m_str[i];
for (int i = 0; i < len; ++i)
{
m_str[pos] = str[i];
pos++;
}
m_size += len;
m_str[m_size] = '\0';
return *this;
}
string& erase(size_t pos)
{
for (int i = pos; i < m_size; ++i)
{
m_str[i] = m_str[i + 1];
}
m_str[--m_size] = '\0';
return *this;
}
public:
void Swap(string &str)
{
swap(m_str, str.m_str);
swap(m_capacity, str.m_capacity);
swap(m_size, str.m_size);
}
private:
char* m_str;
size_t m_capacity;
size_t m_size;
};
ostream& operator<<(ostream& out, const My_string::string& s)
{
for (int i = 0; i < s.m_size; ++i)
out << s.m_str[i];
return out;
}
istream& operator>>(istream& in, My_string::string& s)
{
while (1)
{
char c;
c = in.get();
if (c == '\0' || c == ' ')
break;
else
{
s.push_back(c);
}
return in;
}
}
}
|