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


相关文章
|
25天前
|
C语言 C++ 容器
【c++丨STL】string模拟实现(附源码)
本文详细介绍了如何模拟实现C++ STL中的`string`类,包括其构造函数、拷贝构造、赋值重载、析构函数等基本功能,以及字符串的插入、删除、查找、比较等操作。文章还展示了如何实现输入输出流操作符,使自定义的`string`类能够方便地与`cin`和`cout`配合使用。通过这些实现,读者不仅能加深对`string`类的理解,还能提升对C++编程技巧的掌握。
52 5
|
25天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
39 2
|
1月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
83 5
|
1月前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
80 4
|
1月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
88 4
|
2月前
|
安全 Java 测试技术
Java零基础-StringBuffer 类详解
【10月更文挑战第9天】Java零基础教学篇,手把手实践教学!
52 2
|
2月前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
31 4
|
2月前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
32 4
|
2月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
26 1
|
2月前
|
存储 编译器 C++
【C++类和对象(下)】——我与C++的不解之缘(五)
【C++类和对象(下)】——我与C++的不解之缘(五)