标准库中的string类(上)——“C++”

简介: 标准库中的string类(上)——“C++”

各位CSDN的uu们好呀,好久没有更新小雅兰的C++专栏的知识啦,接下来一段时间,小雅兰就又会开始更新C++这方面的知识点啦,以及期末复习的一些知识点,下面,让我们进入西嘎嘎string的世界吧!!!



string类的常用接口说明


string类的常用接口说明

string类对象的常见构造


函数名称 功能说明
string() (重点) 构造空的string类对象,即空字符串
string(const char* s) (重点) 用C-string来构造string类对象
string(const string&s) (重点) 拷贝构造函数
string(size_t n, char c) string类对象中包含n个字符c
int main()
{
  string s1;//构造空的string类对象s1
  string s2("hello world");//用C格式字符串构造string类对象s2
  string s3 = s2;//拷贝构造s3
  string s4(s2);//拷贝构造s4
}

如果是想要把这些内容打印出来的话,就直接cout就可以了,因为库函数中已经重载了opeator<<!!!

#include<iostream>
#include<string>
using namespace std;
int main()
{
  string s1;//构造空的string类对象s1
  string s2("hello world");//用C格式字符串构造string类对象s2
  string s3 = s2;//拷贝构造s3
  string s4(s2);//拷贝构造s4
  cout << s1 << endl;
  cout << s2 << endl;
  cout << s3 << endl;
  cout << s4 << endl;
  return 0;
}

这些就是最常见的,其余的只需要了解一下就可以了,需要的时候直接查文档!

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

substring constructor
Copies the portion of str that begins at the character position pos and spans len characters (or until the end of str, if either str is too short or if len is string::npos).

str:Another string object, whose value is either copied or acquired.

pos:Position of the first character in str that is copied to the object as a substring.
If this is greater than str's length, it throws out_of_range.
Note: The first character in str is denoted by a value of 0 (not 1).

len:Length of the substring to be copied (if the string is shorter, as many characters as possible are copied).
A value of string::npos indicates all characters until the end of str.

n:Number of characters to copy.

int main()
{
  string s1;//构造空的string类对象s1
  string s2("hello world");//用C格式字符串构造string类对象s2
  string s3 = s2;//拷贝构造s3
  string s4(s2);//拷贝构造s4
  cout << s1 << endl;
  cout << s2 << endl;
  cout << s3 << endl;
  cout << s4 << endl;
  string s5(s2, 0, 5);
  cout << s5 << endl;
  return 0;
}

static const size_t npos = -1//整型的最大值

int main()
{
  string s1;//构造空的string类对象s1
  string s2("hello world");//用C格式字符串构造string类对象s2
  string s3 = s2;//拷贝构造s3
  string s4(s2);//拷贝构造s4
  cout << s1 << endl;
  cout << s2 << endl;
  cout << s3 << endl;
  cout << s4 << endl;
  string s5(s2, 0, 5);
  cout << s5 << endl;
  //下面这两种写法都是从字符串1的位置,取到结束
  string s6(s2, 1);
  string s7(s2, 1, 100);
  cout << s6 << endl;
  cout << s7 << endl;
  return 0;
}

string (const char* s, size_t n);

from buffer

Copies the first n characters from the array of characters pointed by s.

意思是从这个第n个字符开始拷贝,拷贝到目标字符串中!

int main()
{
   string s1;//构造空的string类对象s1
   string s2("hello world");//用C格式字符串构造string类对象s2
   string s3 = s2;//拷贝构造s3
   string s4(s2);//拷贝构造s4
   cout << s1 << endl;
   cout << s2 << endl;
   cout << s3 << endl;
   cout << s4 << endl;
   string s5(s2, 0, 5);
   cout << s5 << endl;
   //下面这两种写法都是从字符串1的位置,取到结束
   string s6(s2, 1);
   string s7(s2, 1, 100);
   cout << s6 << endl;
   cout << s7 << endl;
   string s8(s2, 5);
   cout << s8 << endl;
   return 0;
}

可是,最后的打印结果为什么会是这样的呢?怎么会是打印 world呢?难道不应该是打印hello吗?

原来是用错了!它自动匹配到了上一个函数:string (const string& str, size_t pos, size_t len = npos);

所以:string s8(s2, 5); 这句代码的意思是:从s2的第五个字符开始拷贝,一直拷贝到最后,直到后面再也没有内容!

应该这么写:

int main()
{
  string s1;//构造空的string类对象s1
  string s2("hello world");//用C格式字符串构造string类对象s2
  string s3 = s2;//拷贝构造s3
  string s4(s2);//拷贝构造s4
  cout << s1 << endl;
  cout << s2 << endl;
  cout << s3 << endl;
  cout << s4 << endl;
  string s5(s2, 0, 5);
  cout << s5 << endl;
  //下面这两种写法都是从字符串1的位置,取到结束
  string s6(s2, 1);
  string s7(s2, 1, 100);
  cout << s6 << endl;
  cout << s7 << endl;
  string s8(s2, 5);
  cout << s8 << endl;
  string s9("hello world", 5);
  cout << s9 << endl;
  return 0;
}

 

string (size_t n, char c);

fill constructor

Fills the string with n consecutive(连续的) copies of character c.

int main()
{
  string s1;//构造空的string类对象s1
  string s2("hello world");//用C格式字符串构造string类对象s2
  string s3 = s2;//拷贝构造s3
  string s4(s2);//拷贝构造s4
  cout << s1 << endl;
  cout << s2 << endl;
  cout << s3 << endl;
  cout << s4 << endl;
  string s5(s2, 0, 5);
  cout << s5 << endl;
  //下面这两种写法都是从字符串1的位置,取到结束
  string s6(s2, 1);
  string s7(s2, 1, 100);
  cout << s6 << endl;
  cout << s7 << endl;
  string s8(s2, 5);
  cout << s8 << endl;
  string s9("hello world", 5);
  cout << s9 << endl;
  string s10(10, 'l');
  cout << s10 << endl;
  return 0;
}

string的析构函数:

赋值运算符重载:

int main()
{
  string s1;//构造空的string类对象s1
  string s2("hello world");//用C格式字符串构造string类对象s2
  string s3 = s2;//拷贝构造s3
  string s4(s2);//拷贝构造s4
  cout << s1 << endl;
  cout << s2 << endl;
  cout << s3 << endl;
  cout << s4 << endl;
  string s5(s2, 0, 5);
  cout << s5 << endl;
  //下面这两种写法都是从字符串1的位置,取到结束
  string s6(s2, 1);
  string s7(s2, 1, 100);
  cout << s6 << endl;
  cout << s7 << endl;
  string s8(s2, 5);
  cout << s8 << endl;
  string s9("hello world", 5);
  cout << s9 << endl;
  string s10(10, 'l');
  cout << s10 << endl;
  cout<<endl;
  s1 = s2;
  cout << s1 << endl;
  s1 = "world";
  cout << s1 << endl;
  s1 = 'l';
  cout << s1 << endl;
  return 0;
}

这个赋值支持得很宽泛!因为写了很多重载版本!但是平时用的比较多的是第一种!!!


string类对象的访问及遍历操作

函数名称 功能说明
operator[] (重 点) 返回pos位置的字符,const string类对象调用
begin+end begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭 代器
rbegin+end begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭 代器
范围for C++11支持更简洁的范围for的新遍历方式

opetator[]

int main()
{
  string s1("hello world");
  cout << s1.size() << endl;
  cout << s1.length() << endl;
  for (size_t i = 0; i < s1.size(); i++)
  {
    cout << s1[i] << " ";
  }
  cout << endl;
}

int main()
{
   string s1("hello world");
   cout << s1.size() << endl;
   cout << s1.length() << endl;
   for (size_t i = 0; i < s1.size(); i++)
   {
       //cout << s1[i] << " ";
       cout << s1.operator[](i);————底层原理
   }
   cout << endl;
}

[]既可以读,又可以写!!!

int main()
{
  string s1("hello world");
  cout << s1.size() << endl;
  cout << s1.length() << endl;
  for (size_t i = 0; i < s1.size(); i++)
  {
    cout << s1[i] << " ";
    //cout << s1.operator[](i);
  }
  cout << endl;
  s1[0] = 'z';
  cout << s1 << endl;
}

那如果我现在想要把string逆置一下,那就简单了!

int main()
{
  string s1("hello world");
  cout << s1.size() << endl;
  cout << s1.length() << endl;
  for (size_t i = 0; i < s1.size(); i++)
  {
    cout << s1[i] << " ";
    //cout << s1.operator[](i);
  }
  cout << endl;
  s1[0] = 'z';
  cout << s1 << endl;
 
  //把string逆置一下
  int begin = 0;
  int end = s1.size() - 1;
  while (begin < end)
  {
    char tmp = s1[begin];
    s1[begin] = s1[end];
    s1[end] = tmp;
    begin++;
    end--;
  }
  cout << s1 << endl;
  return 0;
}

这只是其中一种写法,可是,在西嘎嘎中,写这个交换,其实是没有意义的,因为:库函数中给我们提供了这个接口!!!

int main()
{
   string s1("hello world");
   cout << s1.size() << endl;
   cout << s1.length() << endl;
   for (size_t i = 0; i < s1.size(); i++)
   {
       cout << s1[i] << " ";
       //cout << s1.operator[](i);
   }
   cout << endl;
   s1[0] = 'z';
   cout << s1 << endl;

   //把string逆置一下
   int begin = 0;
   int end = s1.size() - 1;
   while (begin < end)
   {
       /*char tmp = s1[begin];
       s1[begin] = s1[end];
       s1[end] = tmp;*/
       swap(s1[begin], s1[end]);
       begin++;
       end--;
   }
   cout << s1 << endl;
   return 0;
}

 

第二种遍历方式:iterator(迭代器)

string::iterator it = s1.begin();
while (it != s1.end())
{
  cout << *it << " ";
  ++it;
}
cout << endl;

也可以修改!

string::iterator it = s1.begin();
while (it != s1.end())
{
  *it += 1;
  cout << *it << " ";
  ++it;
}
cout << endl;

iterator的用法有点像指针!!!但是只是像指针,而不是就是指针!

vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
vector<int>::iterator vit = v.begin();
while (vit != v.end())
{
  cout << *vit << " ";
  ++vit;
}
cout << endl;
list<double> lt;
lt.push_back(1.1);
lt.push_back(2.1);
lt.push_back(3.1);
lt.push_back(4.1);
list<double>::iterator lit = lt.begin();
while (lit != lt.end())
{
  cout << *lit << " ";
  ++lit;
}
cout << endl;


reverse

string::iterator it = s1.begin();
while (it != s1.end())
{
   *it += 1;
   cout << *it << " ";
   ++it;
}
cout << endl;
reverse(s1.begin(), s1.end());
cout << s1 << endl;

vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
vector<int>::iterator vit = v.begin();
while (vit != v.end())
{
   cout << *vit << " ";
   ++vit;
}
cout << endl;
reverse(v.begin(), v.end());
vit = v.begin();
while (vit != v.end())
{
   cout << *vit << " ";
   ++vit;
}
cout << endl;

list<double> lt;
lt.push_back(1.1);
lt.push_back(2.1);
lt.push_back(3.1);
lt.push_back(4.1);
list<double>::iterator lit = lt.begin();
while (lit != lt.end())
{
   cout << *lit << " ";
   ++lit;
}
cout << endl;
reverse(lt.begin(), lt.end());
lit = lt.begin();
while (lit != lt.end())
{
   cout << *lit << " ";
   ++lit;
}
cout << endl;


之前,我们手撕了一个string的逆置,但其实,西嘎嘎的库函数里面就有这个函数!

string、vector、list都逆置过来了!!!

之前的那个operator[],提供了两个版本:

    char& operator[] (size_t pos);

const char& operator[] (size_t pos) const;

第一个可以编译通过,第二个不能编译通过!

编译器会去找更匹配的!

int main()
{
  string s1("hello world");
  const string s2("hello world");
  s1[0] = 'x';
  //s2[0] = 'x';
  cout << s2[0] << endl;
 
  string::const_iterator it = s2.begin();
  while (it != s2.end())
  {
    //*it += 1;
    cout << *it << " ";
    ++it;
  }
  cout << endl;
  return 0;
}

for (auto e : s1)
{
   cout << e << " ";
}
cout << endl;

但是实际上,迭代器才是yyds!


所以,现在我们遍历,就有三种方法:

  • 下标+[]
  • 迭代器
  • 范围for

但是,主流还是迭代器!!!

void func(const string& s)
{
  string::const_reverse_iterator it = s.rbegin();
  while (it != s.rend())
  {
    cout << *it << " ";
    ++it;
  }
  cout << endl;
}
int main()
{
  string s1("hello world");
  string::reverse_iterator it1 = s1.rbegin();
  while (it1 != s1.rend())
  {
    cout << *it1 << " ";
    ++it1;
  }
  cout << endl;
  func(s1);
  return 0;
}



好啦,小雅兰今天的西嘎嘎string的使用部分就到这里啦,下一篇博客继续string的使用,后续还会写string模拟实现,加油!!!


相关文章
|
11天前
|
Java 索引
java基础(13)String类
本文介绍了Java中String类的多种操作方法,包括字符串拼接、获取长度、去除空格、替换、截取、分割、比较和查找字符等。
24 0
java基础(13)String类
|
8天前
|
安全 Java
String类-知识回顾①
这篇文章回顾了Java中String类的相关知识点,包括`==`操作符和`equals()`方法的区别、String类对象的不可变性及其好处、String常量池的概念,以及String对象的加法操作。文章通过代码示例详细解释了这些概念,并探讨了使用String常量池时的一些行为。
String类-知识回顾①
|
6天前
|
并行计算 Unix Linux
超级好用的C++实用库之线程基类
超级好用的C++实用库之线程基类
12 4
|
17天前
|
安全 Java
Java StringBuffer 和 StringBuilder 类详解
在 Java 中,`StringBuffer` 和 `StringBuilder` 用于操作可变字符串,支持拼接、插入、删除等功能。两者的主要区别在于线程安全性和性能:`StringBuffer` 线程安全但较慢,适用于多线程环境;`StringBuilder` 非线程安全但更快,适合单线程环境。选择合适的类取决于具体的应用场景和性能需求。通常,在不需要线程安全的情况下,推荐使用 `StringBuilder` 以获得更好的性能。
|
6天前
|
C++ Windows
HTML+JavaScript构建C++类代码一键转换MASM32代码平台
HTML+JavaScript构建C++类代码一键转换MASM32代码平台
|
6天前
|
C++
2合1,整合C++类(Class)代码转换为MASM32代码的平台
2合1,整合C++类(Class)代码转换为MASM32代码的平台
|
6天前
|
存储 运维 监控
超级好用的C++实用库之日志类
超级好用的C++实用库之日志类
13 0
|
11天前
|
Java 索引
java基础扫盲-String类常用的方法
java基础扫盲-String类常用的方法
|
2月前
|
API 索引
String类下常用API
String类下常用API
38 1
|
2月前
for循环和String类下方法的一个练习题
for循环和String类下方法的一个练习题
45 1
下一篇
无影云桌面