【C++String类使用】万字详解保姆级教学,手把手教你使用string类。2

简介: 【C++String类使用】万字详解保姆级教学,手把手教你使用string类。

返回迭代器结束
返回指向字符串的结尾字符的迭代器。

理解了这两个迭代器函数。我们来运行上面代码看结果>

a299e1bbebf24346ae851f447723b4db.png


注:itertor是像指针一样的类型,有可能是指针,有可能不是指针。 具体是什么,我们以后再来探讨。

迭代器也是可以对数据进行修改的

int main()
{
  string s1("hello C++");
  cout << s1 << endl;
  string::iterator it = s1.begin();
  while (it != s1.end())
  {
    //通过迭代器对s1中的字符进行--
    (*it)--;
    ++it;
  }
  /让s1.begin()重新指向开头位置
  it = s1.begin();
  while (it != s1.end())
  {
    cout << *it << " ";
    ++it;
  }
  cout << endl;
  return 0;
}

391c7d425f0d498fae6e47a932358565.png


reverse_iterator反向迭代器

如果想要倒着打印字符串也可以通过反向迭代器来进行操作>

int main()
{
  string s1("hello C++");
  cout << s1 << endl;
  string::reverse_iterator it = s1.rbegin();
  while (it != s1.rend())
  {
    cout << *it ;
    ++it;
  }
  cout << endl;
  return 0;
}


上面代码中的s1.rbegin()返回反向迭代器到反向开始,返回指向字符串最后一个字符,s1.rend()返回反向迭代器到反向结束返回指向字符串第一个字符之前的理论元素的反向迭代。


616f511821af4c0f9954e6f02b52abc3.png

rbegin() 返回一个反向迭代器,指向 string 对象中最后一个字符。


2bffe445aad240b7a3bdf05b04a96978.png


rend()返回一个反向迭代器,指向 string 对象中第一个字符之前的位置。

了解了上面两个函数我们再来运行上面代码看结果>


4e304f66aacc441b8ab5265ee57001f3.png


范围for

C++11支持更简洁的范围for的新遍历方式

使用方法也是很简单,来看一段代码>


int main()
{
  string s1("hello C++");
  //for(char& ch : s1)
  for (auto& ch : s1)
  {
    cout << ch;
  }
  cout << endl;
  return 0;
}

1625169187d54020845d2b26d722a1d9.png



上面for (auto& ch : s1)的意思是依次取出s1中的字符传给ch,再对ch进行打印。auto是自动识别类型,当然我们也可以写成for (char& ch : s1),在我们日常中经常使用auto自动识别类型。

当然也可以通过范围for对字符串中的内容进行修改。


int main()
{
  string s1("hello C++");
  for (auto& ch : s1)
  {
    ch++;
  }
  for (auto& ch : s1)
  {
    cout << ch;
  }
  cout << endl;
  return 0;
}

63098100e0ef43e4ad0f96eb693e220d.png

范围for底层实现原理

范围for底层其实就是调用使用迭代器来完成>



79ae35496ccd4170a3bad129947bdf69.png


通过反汇编代码我们可以看到在我们使用范围for的时候调用了两个迭代器函数,分别是begin()和end()。

string类对象的修改操作

push_back()

56cbad5fe3404925adf9c15cd8d72ee3.png


将字符附加到字符串
将字符c附加到字符串的末尾,将其长度增加一。


int main()
{
  string str("hello C+");
  cout << str << endl;
  str.push_back('+');
  cout << str << endl;
  return 0;
}


2c90f2164230443ea4e177a73d8b6832.png

append()

c3493cc8e3ed48ba9c9d52e33554330c.png

附加到字符串
通过在当前值的末尾附加额外的字符来 扩展字符串:

append也重载了许多个函数。我们这里介绍几个比较常用的。


string& append (const string& str);

这个函数的功能是追加str的拷贝。

eg:

int main()
{
  string str1("hello ");
  string str2("C++");
  str1.append(str2);
  cout << str1 << endl;
  return 0;
}


91ea5b221c9e41ea9f770b4e5ee8f6c6.png


string& append (const string& str, size_t subpos, size_t sublen);

追加str的子字符串的副本。子字符串是str的一部分,它从字符位置subpos开始并跨越sublen个字符(或者直到str的结尾,如果str太短或者sublen是string::npos)。

eg:


int main()
{
  string str1("hello ");
  string str2("C++");
  str1.append(str2,0,2);
  cout << str1 << endl;
  return 0;
}

a41b740a0fe74e2f87a681a5e2b7a405.png


从str2的第0个位置开始追加追加两个字符。

string& append (const char* s);

在字符串后面追加一个字符串。

eg:


int main()
{
  string str1("hello ");
  str1.append("C++");
  cout << str1 << endl;
  return 0;
}

7f4f5208f42546dab6ff3d06eb8552af.png


string& append (const char* s, size_t n);

在s指向的字符数组中追加前n个字符的副本。

eg:

int main()
{
  string str1("hello ");
  str1.append("C++! hello",3);
  cout << str1 << endl;
  return 0;
}


62fe0635f38044a2ac11a9b1f632e412.png


在str后面追加"C++ hello"字符串中的前三个字符。

string& append (size_t n, char c);

填充
追加字符c的n 个连续拷贝。

eg:


int main()
{
  string str1("hello C");
  str1.append(2,'+');
  cout << str1 << endl;
  return 0;
}


fb60e3f6233249c385684660f063aefc.png

operator +=

7789c4b2ec0d4f0c993ef8c3134409d1.png



这个重载也是字符串追加的功能。可以追加string对象,可以追加字符串,也可以追加单个字符。

eg:

int main()
{
  string name("John");
  string family("Smith");
  name += " K. ";         // c-string
  name += family;         // string
  name += '\n';           // character
  cout << name;
  return 0;
}

2b151e85eb6042768f326bbe3a16f3ff.png



c_str()

8e27323bc38e499fb07cb6bcb42afbc2.png


c_str()string 类的成员函数,用于返回一个指向 string 对象中第一个字符的指针。该指针指向的字符数组以空字符结尾,可以用于与 C 风格字符串进行交互。以下是 c_str() 的用法和示例:

#include <iostream>
#include <string>
int main() {
    std::string str = "hello";
    const char *cstr = str.c_str();
    std::cout << cstr << std::endl; // hello
    return 0;
}

在上面的示例中,我们首先创建了一个 string 对象 str,然后使用 c_str() 函数将其转换为 C 风格字符串,并将返回的指针存储在 const char *cstr 中。最后,我们使用 std::cout 输出了 cstr 指向的字符数组。需要注意的是,由于 c_str() 返回的指针指向的字符数组是以空字符结尾的,因此可以使用该指针与 C 风格字符串进行交互。


find + npos


5ab02309d2ef4ad5ab7a62cbd0a68c86.png


find()string 类的成员函数,用于在字符串中查找指定的子串,并返回其位置。nposstring 类的静态成员变量,表示未找到指定子串时的返回值。以下是 find()npos 的用法和示例:


#include <iostream>
#include <string>
int main() {
    std::string str = "hello world";
    std::string sub = "world";
    std::size_t pos = str.find(sub);
    if (pos != std::string::npos) {
        std::cout << "Substring found at position " << pos << std::endl;
    } else {
        std::cout << "Substring not found" << std::endl;
    }
    return 0;
}

在上面的示例中,我们首先创建了一个 string 对象 str,然后使用 find() 函数查找字符串 "world" 在 str 中的位置,并将返回值存储在 pos 中。接着,我们使用 if 语句判断 pos 是否等于 std::string::npos,如果不等于,则说明找到了子串,输出其位置;否则说明未找到子串,输出提示信息 "Substring not found"。


需要注意的是,find() 函数可以接受一个可选的参数,用于指定搜索起始位置。例如,如果我们想从 str 的第 7 个字符开始查找子串,可以将其作为 find() 函数的第二个参数传入:


std::size_t pos = str.find(sub, 7);

这样就会从第 7 个字符开始查找子串。


另外,需要注意的是,npos 的值是一个特殊值,表示未找到指定子串时的返回值。它的值是一个无符号整数,通常是一个非常大的数值,因此可以用于判断 find() 函数是否查找到了指定子串。

注意:


在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般

情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。

对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。


string类非成员函数

我们上面一直在使用cout<<str<<endl;在对字符串进行打印输出,string不是内置类型,为什么还可以使用输出<<打印呢?

这是因为string类外面重载了operator<<(string)和operator>>(string)。


5f26453867724e55892c1286c430d144.png

将字符串插入流
将符合str 值的字符序列插入到os中。
此函数重载operator<<使其行为如ostream::operator<<中所述,适用于 C 字符串,也适用于字符串对象。


53dc80cb2e534c9896fac12f638437d0.png

从流中提取字符串

从输入流is中提取一个字符串,将序列存储在str中,它被覆盖( str的先前值被替换)。

此函数重载operator>>使其行为如istream::operator>>中描述的用于 c 字符串,但应用于字符串对象。

每个提取的字符都附加到字符串,就好像它的成员push_back被调用一样。


getline

22156feeda044d92ada8bda42cc4d2f6.png

getline 是 C++ 中 string 类的一个成员函数,用于从输入流中获取一行数据。它的使用方法如下:

int main() {
  string name;
  cout << "请输入你的名字>";
  getline(cin, name);
  cout << "Hello " << name << endl;
  return 0;
}


e6b22add35b64368aa7fe654ad8d4859.png

在上面的例子中,我们使用 getline 从标准输入流 std::cin 中读取一行数据,并将其存储到 line 变量中。然后,我们将这个字符串输出到标准输出流 std::cout 中。

也可以指定一个分隔符来代替默认的换行符 \n。例如,如果你想使用逗号作为分隔符,可以这样写:

int main() {
  std::string name;
  std::cout << "请输入你的名字>";
  std::getline(std::cin, name, ',');
  std::cout << "Hello " << name << std::endl;
  return 0;
}


2afd47b7dfc246f386bb1ac19b71f0be.png


在上面的例子中,我们使用逗号作为分隔符来读取输入流中的一行数据。

relational operators (string)字符串比较函数

27fd811fa6fd411f9d53936163cac9c2.png

relational operators 是 string 类的比较运算符,用于比较两个 string 类型的对象。

以下是 relational operators 的用法和示例:


== 运算符:判断两个 string 对象是否相等,如果相等则返回 true,否则返回 false。


#include <iostream>
#include <string>
int main() {
    std::string str1 = "hello";
    std::string str2 = "world";
    std::string str3 = "hello";
    std::cout << std::boolalpha << (str1 == str2) << std::endl; // false
    std::cout << std::boolalpha << (str1 == str3) << std::endl; // true
    return 0;
}
  1. != 运算符:判断两个 string 对象是否不相等,如果不相等则返回 true,否则返回 false


#include <iostream>
#include <string>
int main() {
    std::string str1 = "hello";
    std::string str2 = "world";
    std::string str3 = "hello";
    std::cout << std::boolalpha << (str1 != str2) << std::endl; // true
    std::cout << std::boolalpha << (str1 != str3) << std::endl; // false
    return 0;
}
  1. < 运算符:判断一个 string 对象是否小于另一个 string 对象,如果是则返回 true,否则返回 false
#include <iostream>
#include <string>
int main() {
    std::string str1 = "hello";
    std::string str2 = "world";
    std::string str3 = "abc";
    std::cout << std::boolalpha << (str1 < str2) << std::endl; // true
    std::cout << std::boolalpha << (str1 < str3) << std::endl; // false
    return 0;
}


  1. > 运算符:判断一个 string 对象是否大于另一个 string 对象,如果是则返回 true,否则返回 false


#include <iostream>
#include <string>
int main() {
    std::string str1 = "hello";
    std::string str2 = "world";
    std::string str3 = "abc";
    std::cout << std::boolalpha << (str1 > str2) << std::endl; // false
    std::cout << std::boolalpha << (str1 > str3) << std::endl; // true
    return 0;
}


5.<= 运算符:判断一个 string 对象是否小于或等于另一个 string 对象,如果是则返回 true,否则返回 false


#include <iostream>
#include <string>
int main() {
    std::string str1 = "hello";
    std::string str2 = "world";
    std::string str3 = "abc";
    std::cout << std::boolalpha << (str1 <= str2) << std::endl; // true
    std::cout << std::boolalpha << (str1 <= str3) << std::endl; // false
    return 0;
}
  1. >= 运算符:判断一个 string 对象是否大于或等于另一个 string 对象,如果是则返回 true,否则返回 false
#include <iostream>
#include <string>
int main() {
    std::string str1 = "hello";
    std::string str2 = "world";
    std::string str3 = "abc";
    std::cout << std::boolalpha << (str1 >= str2) << std::endl; // false
    std::cout << std::boolalpha << (str1 >= str3) << std::endl; // true
    return 0;
}


上面的几个接口大家了解一下,string类中还有一些其他的操作,这里不一一列举,大家在需要用到时不明白了查文档即可。


🍀小结🍀

今天我们认识了C++string类的用法相信大家看完有一定的收获。

种一棵树的最好时间是十年前,其次是现在! 把握好当下,合理利用时间努力奋斗,相信大家一定会实现自己的目标!加油!创作不易,辛苦各位小伙伴们动动小手,三连一波💕💕~~~,本文中也有不足之处,欢迎各位随时私信点评指正!

相关文章
|
6天前
|
C++ 容器
C++中自定义结构体或类作为关联容器的键
C++中自定义结构体或类作为关联容器的键
13 0
|
6天前
|
存储 算法 搜索推荐
【C++】类的默认成员函数
【C++】类的默认成员函数
|
6天前
|
安全 编译器 C语言
【C++数据结构】string的模拟实现
【C++数据结构】string的模拟实现
|
6天前
|
存储 安全 编译器
【C++】类和对象(下)
【C++】类和对象(下)
【C++】类和对象(下)
|
4天前
|
编译器 C++
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
|
4天前
|
编译器 C++
virtual类的使用方法问题之静态和非静态函数成员在C++对象模型中存放如何解决
virtual类的使用方法问题之静态和非静态函数成员在C++对象模型中存放如何解决
|
4天前
|
编译器 C++
virtual类的使用方法问题之在C++中获取对象的vptr(虚拟表指针)如何解决
virtual类的使用方法问题之在C++中获取对象的vptr(虚拟表指针)如何解决
|
6天前
|
编译器 C++
【C++】类和对象(中)
【C++】类和对象(中)
|
6天前
|
存储 编译器 程序员
【C++】类和对象(上)
【C++】类和对象(上)
|
6天前
|
存储 编译器 C++
【C++】类和对象(下)
【C++】类和对象(下)