C++STL——string类与模拟实现(上)

简介: C++STL——string类与模拟实现

什么是STL

STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。

STL的六大组成:仿函数,算法,迭代器,空间配置器,容器,配接器。

注意:

这里我是按照功能归类讲string归类到了STL里面,如果按照发展史其实并不属于STL中的容器。

并且从现在开始我们会更频繁的开始使用这个网站了:

cpulspuls

string类

为什么要学习string呢?C语言中字符串是以‘\0’结尾的,C语言当中提供的str库函数是与字符串分开的,很可能越界访问,也不方便管理,C++主要是OOP思想(抽象”、“封装”、“继承”、“多态),所以出现了string,并且更方便增删查改。

字符串的标准

计算机是二进制,但是如果让我们去理解一堆0和1组成的是什么意思很难理解,所以就有了编码(计算机存值——文字符号,对应关系):

这些符号就可以组成很多东西了,比如数值,单词等等。

如果你想储存abc,那么在内存中储存的就是

97 98 99

想让计算机流通全世界,那么就要支持各个国家的语言,这个时候就出现了统一码

在UTF-8中将常用的汉字用两个字节去存储,256*256=65536。(但是这里要兼容ASCII码值所以没有这么多)

有些生僻字需要三个或者四个字节去储存。

UTF-16不兼容ASCII码值,起步用2个字节。

UTF-32不兼容ASCII码值,起步用4个字节。

但是中华文化博大精深,国内又针对函数定义了新的标准,GBK

什么是string

string是字符串的类,该类添加了很多接口便于操作string类。

string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;

不能操作多字节和变长字节序列。

cplusplus中是这样描述的:

string常用接口介绍

string的初始化

string()构造空string类的对象
string(const char* s)用字符串初始化新构造string类的的对象
string(const string&s)用string类对象构造新的string类对象

这类接口是调用构造函数。

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s("abc");//创建string类s,给s初始化abc
  cout << s << endl;
  string s1;//创建string类s1,不进行初始化
  cout << s1 << endl;
  string s2(s);//将s拷贝到s2中
  cout << s2 << endl;
  return 0;
}

比较大小与赋值

比较的是字符串的ASCII码值。

这些接口都是对于运算符进行重载。

先来看赋值:

string& operator= (const string& str);赋值string类的对象

string& operator= (const char* s);赋值字符串

string& operator= (char c);赋值一个字符

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s1("abc");
  cout << s1 << endl;
  string s2;
  s2 = s1;//赋值string类的对象
  cout << s2 << endl;
  string s3;
  s3 = "adc";//赋值字符串
  cout << s3 << endl;
  s3 = 's';//赋值一个字符
  cout << s3 << endl;
  return 0;
}

等于,大于,小于等:

返回值为bool,参数是引用类。

正确返回1,错误返回0.

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s1("abc");
  string s2("adc");
  string s3("abc");
  string s4("abb");
  cout << "==:" << endl;
  cout << (s1 == s2) << endl;
  cout << (s1 == s3) << endl;
  cout << "< <=:" << endl;
  cout << (s1 < s2) << endl;
  cout << (s1 <= s2) << endl;
  cout << (s1 < s3) << endl;
  cout << (s1 <= s3) << endl;
  cout << (s1 <= s4) << endl;
  cout << "> >=:" << endl;
  cout << (s1 > s2) << endl;
  cout << (s1 >= s2) << endl;
  cout << (s1 >= s3) << endl;
  cout << (s1 > s4) << endl;
  cout << (s1 >= s4) << endl;
  return 0;
}

容量

这里要注意容量和有效字符长度的区别。

size返回字符串有效长度
capacity返回有效容量长度

size_t size() const;

size_t capacity() const;

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s("qwert");
  cout << s.size() << endl;
  cout << s.capacity() << endl;
  return 0;
}

这里有一个与size功能相同的接口length。(原因是因为命名的习惯)

empty检测对象是否为空字符串,空返回1,非空返回0
clear清空对象中的有效字符串

bool empty() const;

void clear();

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s("qwert");
  cout << s.empty() << endl;
  s.clear();//这里并不改变容量大小
  cout << s.empty() << endl;
  return 0;
}

reserve为字符串预留空间
resize将有效字符串变成指定长度,多出的长度用指定字符补上

void reserve (size_t n = 0);

void resize (size_t n);

void resize (size_t n, char c);

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s;
  s.reserve(1000);//内存对齐会多出一些空间,总大小至少是n
  cout << s.capacity() << endl;
  s.reserve(15);//VS编译器下15及以下才会缩容,前提是原来对象中字符串不能超过15个长度
  cout << s.capacity() << endl;
  string s1("qwert");
  cout << s1 << endl;
  int sz = s1.size();
  s1.resize(4);//不到原本字符串长度就将后面的字符串覆盖
  cout << s1 << endl;
  s1 = "qwert";
  s1.resize(4, 'x');//不到原本字符串长度就将后面的字符串覆盖
  cout << s1 << endl;
  s1 = "qwert";
  s1.resize(8, 'x');//不足就用字符x补上
  cout << s1 << endl;
  return 0;
}

对象的修改

push_back在后面追加一个字符
append在后面追加一个字符串
operator+=在后面追加一个字符串或字符还有对象

void push_back (char c);

string& append (const char* s);

string& operator+= (const string& str);

string& operator+= (const char* s);

string& operator+= (char c);

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s("qwe");
  string s1("123");
  s += 'r';
  cout << s << endl;
  s += "ty";
  cout << s << endl;
  s += s1;
  cout << s << endl;
  string s2("zxc");
  s2.push_back('v');
  cout << s2 << endl;
  s2.append("cpp");
  cout << s2 << endl;
  return 0;
}

insert在指定位置插入指定内容(不推荐,时间复杂度高)
pop_back尾删
erase从指定位置删除指定长度的字符(不推荐,时间复杂度高)
c_str返回C语言的字符串

string& insert (size_t pos, const string& str);

string& insert (size_t pos, const char* s);

void pop_back();

string& erase (size_t pos = 0, size_t len = npos);

const char* c_str() const;

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s("qwert");
  string s1("zxc");
  s.insert(1, "ccc");
  cout << s << endl;
  s.insert(0, s1);
  cout << s << endl;
  s.pop_back();
  cout << s << endl;
  s.erase(2, 4);
  cout << s << endl;
  cout << s.c_str() << endl;//这里是为了方便做返回值
}

find + npos从指定位置向后查找指定位置的字符(npos是string类中特殊的静态常量-1)
rfind从指定位置向前查找指定位置的字符
substr从指定位置截取n个字符返回

size_t find (const string& str, size_t pos = 0) const;

size_t find (const char* s, size_t pos = 0) const;

size_t rfind (const string& str, size_t pos = npos) const;

size_t rfind (const char* s, size_t pos = npos) const;

string substr (size_t pos = 0, size_t len = npos) const;

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s("test.cpp");
  int num = s.find("st", 0);
  cout << num << endl;
  num = s.find("st", 5);
  cout << num << endl;
  num = s.rfind("cpp", 7);
  cout << num << endl;
  num = s.rfind("cpp", 4);
  cout << num << endl;
  string s1 = s.substr(0, 4);
  cout << s1 << endl;
  return 0;
}

相关文章
|
3天前
|
存储 安全 Java
Java——String类详解
String 是 Java 中的一个类,用于表示字符串,属于引用数据类型。字符串可以通过多种方式定义,如直接赋值、创建对象、传入 char 或 byte 类型数组。直接赋值会将字符串存储在串池中,复用相同的字符串以节省内存。String 类提供了丰富的方法,如比较(equals() 和 compareTo())、查找(charAt() 和 indexOf())、转换(valueOf() 和 format())、拆分(split())和截取(substring())。此外,还介绍了 StringBuilder 和 StringJoiner 类,前者用于高效拼接字符串,后者用于按指定格式拼接字符串
10 1
Java——String类详解
|
14天前
|
存储 编译器 C++
C ++初阶:类和对象(中)
C ++初阶:类和对象(中)
|
14天前
|
C++
C++(十六)类之间转化
在C++中,类之间的转换可以通过转换构造函数和操作符函数实现。转换构造函数是一种单参数构造函数,用于将其他类型转换为本类类型。为了防止不必要的隐式转换,可以使用`explicit`关键字来禁止这种自动转换。此外,还可以通过定义`operator`函数来进行类型转换,该函数无参数且无返回值。下面展示了如何使用这两种方式实现自定义类型的相互转换,并通过示例代码说明了`explicit`关键字的作用。
|
14天前
|
存储 设计模式 编译器
C++(十三) 类的扩展
本文详细介绍了C++中类的各种扩展特性,包括类成员存储、`sizeof`操作符的应用、类成员函数的存储方式及其背后的`this`指针机制。此外,还探讨了`const`修饰符在成员变量和函数中的作用,以及如何通过`static`关键字实现类中的资源共享。文章还介绍了单例模式的设计思路,并讨论了指向类成员(数据成员和函数成员)的指针的使用方法。最后,还讲解了指向静态成员的指针的相关概念和应用示例。通过这些内容,帮助读者更好地理解和掌握C++面向对象编程的核心概念和技术细节。
|
14天前
|
存储 C++
C++(五)String 字符串类
本文档详细介绍了C++中的`string`类,包括定义、初始化、字符串比较及数值与字符串之间的转换方法。`string`类简化了字符串处理,提供了丰富的功能如字符串查找、比较、拼接和替换等。文档通过示例代码展示了如何使用这些功能,并介绍了如何将数值转换为字符串以及反之亦然的方法。此外,还展示了如何使用`string`数组存储和遍历多个字符串。
|
21天前
|
缓存 安全 Java
Java String类
Java String类
13 0
|
1月前
|
C++ 容器
C++中自定义结构体或类作为关联容器的键
C++中自定义结构体或类作为关联容器的键
31 0
|
1月前
|
存储 安全 编译器
【C++】类和对象(下)
【C++】类和对象(下)
【C++】类和对象(下)
|
27天前
|
存储 算法 编译器
c++--类(上)
c++--类(上)
|
1月前
|
编译器 C++
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决