【C++】学习笔记——string_3

简介: 【C++】学习笔记——string_3

六、string类

5. string类的操作

上面的函数中,有些是不常用的,咱们只挑几个重要的进行讲解。

c_str 就是将字符串转换成 C语言 字符串的格式。

get_allocator 就是申请内存池,目前用不上。

copy 就是拷贝,缺点是必须先创建好一个字符数组,字符数组还是形参,返回拷贝的个数,被下面的 substr 函数完虐。substr 函数返回一个 string 类型。

假设有个情景:需要我们找出文件名的后缀,该怎么办?

#include<iostream>
#include<string>
using namespace std;
void test1()
{
  string s("file.cpp");
  // find函数返回第一个出现的下标
  size_t pos = s.find('.');
  // 在string类里,没找到都会以npos的形式返回。
  if (pos != string::npos)
  {
    string suffix = s.substr(pos);
    cout << suffix << endl;
  }
}
int main()
{
  test1();
  return 0;
}

find 函数

substr 函数

那么假设这个文件里 . 很多,我们要返回最后一个后缀,该怎么办?这个时候,就到了 rfind 大展身手的时候了,rfind 函数也是查找,不过是从后往前查找。

#include<iostream>
#include<string>
using namespace std;
void test2()
{
  string s("file.cpp.rar.zip.tar");
  size_t pos = s.rfind('.');
  if (pos != string::npos)
  {
    string suffix = s.substr(pos);
    cout << suffix << endl;
  }
}
int main()
{
  test2();
  return 0;
}

再假设一个情景,有一个网址,将其 协议域名资源名 给分离开,怎么搞呢?

#include<iostream>
#include<string>
using namespace std;
void test3()
{
  string url("https://cplusplus.com/reference/string/string/substr/");
  // 协议
  string protocol;
  // 域名
  string domain;
  // 资源名
  string uri;
  size_t i1 = url.find(":");
  if (i1 != string::npos)
  {
    protocol = url.substr(0, i1 - 0);
    cout << protocol << endl;
  }
  // 从域名开始找 '/'
  size_t i2 = url.find('/', i1 + 3);
  if (i2 != string::npos)
  {
    domain = url.substr(i1 + 3, i2 - i1 - 3);
    cout << domain << endl;
    // 剩下的都是资源名
    uri = url.substr(i2 + 1);
    cout << uri << endl;
  }
}
int main()
{
  test3();
  return 0;
}

compare 就是比较,不过 string 针对比较都做了重载,可用直接用 > ! = 等比较。

6. string类的转换

当我们涉及到其他类型转换成字符串类型时,有这样一个函数:

#include<iostream>
#include<string>
using namespace std;
void test4()
{
  int a = 123456;
  string s = to_string(a);
  cout << s << endl;
}
int main()
{
  test4();
  return 0;
}

当然,有其他类型转换成字符串类型,就有字符串类型转换成其他类型。

#include<iostream>
#include<string>
using namespace std;
void test5()
{
  string s1("13579");
  string s2("3.1415926");
  int i = stoi(s1);
  double d = stod(s2);
  cout << i << endl << d << endl;
}
int main()
{
  test5();
  return 0;
}

7. string类的模拟实现

接下来我们来具体实现一下 string 类。在实现 string 类的时候,我们需要将其封装一下,包含在自己的命名空间下。

// string.h 头文件下
#pragma once
#include<iostream>
// 我们自己实现的 string 类的专属命名空间
namespace my
{
  class string
  {
  public:
    //
  private:
    // 字符数组 存数据
    char* _str;
    // 无符号整形 存数据个数、字符串的长度
    size_t _size;
    // 存为该字符串已经分配的空间、容量
    size_t _capacity;
  };
}

接下来我们来实现构造函数,分为无参构造函数,和有参构造函数。

// my 命名空间下
class string
{
public:
  // 无参构造函数
  string()
    :_str(nullptr)  // 初始化列表
    ,_size(0)
    ,_capacity(0)
  {}
  // 有参构造函数
  string(const char* str)
    :_size(strlen(str))
  {
    _capacity = _size;
    _str = new char[_capacity + 1];
    strcpy(_str, str);
  }
private:
  char* _str;
  size_t _size;
  size_t _capacity;
};

构造函数不一定非要使用初始化列表,我们在有参构造函数里面若是使用初始化列表,由于三个对象都需要调用 strlen 函数,导致效率不高,所以可以初始化列表和赋值一起使用。


未完待续

目录
相关文章
|
1月前
|
C++ 容器
|
30天前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
21 1
|
1月前
|
C++ 容器
|
1月前
|
C++ 容器
|
1月前
|
存储 C++ 容器
|
1月前
|
C语言 C++
深度剖析C++string(中)
深度剖析C++string(中)
47 0
|
1月前
|
存储 编译器 程序员
深度剖析C++string(上篇)(2)
深度剖析C++string(上篇)(2)
35 0
|
1月前
|
存储 Linux C语言
深度剖析C++string(上篇)(1)
深度剖析C++string(上篇)(1)
29 0
|
1月前
|
C++
|
1月前
|
C语言 C++
C++番外篇——string类的实现
C++番外篇——string类的实现
20 0