标准库中的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模拟实现,加油!!!


相关文章
|
1天前
|
存储 编译器 C++
【C++】String -- 详解(下)
【C++】String -- 详解(下)
|
1天前
模拟实现string类--重载输入输出流
模拟实现string类--重载输入输出流
|
1天前
|
存储 JavaScript C语言
【C++】String -- 详解(上)
【C++】String -- 详解(上)
|
1天前
|
编译器 C++
【C++】类和对象(下)
【C++】类和对象(下)
|
1天前
|
编译器 C++
【C++】类和对象(中)(2)
【C++】类和对象(中)(2)
|
1天前
|
存储 编译器 C++
【C++】类和对象(中)(1)
【C++】类和对象(中)(1)
|
1天前
|
存储 编译器 C语言
【C++】类和对象(上)
【C++】类和对象(上)
|
1天前
|
存储 编译器 C++
C++ 存储类
C++ 存储类
9 0
|
11小时前
|
存储 Java API
【JAVA学习之路 | 提高篇】[内部类与常见API]String类
【JAVA学习之路 | 提高篇】[内部类与常见API]String类
|
5天前
|
存储 安全 Java
Java中的这些String特性可能需要了解下
Java中的String特性你知道哪些?虽然String很常见,通过源码可以看到String的值传递、字符串表和不可变性。本文基于JDK17说明。
11 1