欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > cpp详解:string

cpp详解:string

2025/3/11 15:40:03 来源:https://blog.csdn.net/muzibuku/article/details/142980460  浏览:    关键词:cpp详解:string

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、string是什么?
  • 二、使用string
    • string:operator +
    • operator[]
    • string:.at()
    • operator+=
    • operator>> ,输出(operator<< )
  • 三、常见函数
    • string()
    • size()和length()
    • empty ()
    • clear()
    • reserve()和resize()
      • reserve()
      • resize()
    • begin()+ end()
      • begin()
      • endl()
    • find() + npos()
      • find()
      • npos()
    • 作者怨念


前言

在cpp的学习中stl是非常重要的重要的的一步甚至有人说不会stlcpp只学了一半,下面我们就好好学习stl中的很重要的库string


一、string是什么?

在百度百科中是这么形容string的:string是C++、java、VB等编程语言中的字符串,用双引号引起来的几个字符,如"Abc",“一天”.字符串是一个特殊的对象,属于引用类型。 在java、C#中,String类对象创建后,字符串一旦初始化就不能更改,因为string类中所有字符串都是常量,数据是无法更改,由于string对象的不可变,所以可以共享。对String类的任何改变,都是返回一个新的String类对象。 C++标准库中string类以类型的形式对字符串进行封装,且包含了字符序列的处理操作
在这里我们只讨论cpp中的string。
C++ 标准库(Standard Template Library, STL)是 C++ 的核心组成部分之一,提供了丰富的数据结构和算法。
< string> 是 C++ 标准库中用于处理字符串的头文件。
在 C++ 中,字符串是由字符组成的序列。头文件提供了 类,它是对 C 风格字符串的封装,提供了更安全、更易用的字符串操作功能。std::string
要在 C++ 程序中使用 库,首先需要包含这个头文件:< string>

二、使用string

在前面我们已经了解了什么是string下面我们就来看如何使用string,因为它是一个库所以我们要加上它的头文件例子如下

#include <iostream>
#include<string>
using namespace std;
int main()
{string sl;sl="hello cpp"; string sl2(sl);cout << sl2 << endl;cout<<sl<<endl;}

在这段例子中我创建了一个string,你可以理解成一个字符串,这个字符串的大小可以自动扩大,在你没有写入时它就是一个空字符串。虽然你可以将 sl 理解成字符串但是它的使用可比字符串要方便的多比如它连接字符串可以直接+

string:operator +

先写一段代码来帮助理解

#include <iostream>
#include<string>
using namespace std;
int main()
{string sl;sl = "hello\n";sl = sl + " hello";cout << sl << endl;}

在这段代码中它的输出便是

hellohello

这段代码可以清楚的看见这两个字符串已经连接好了。但是这并不是+本来的作用而是被人为定义的,是编译人员来重新定义的,这样的列子还有很多在string中比如我赋们已经看过的赋予值(operator=),位置(operator[]),追加(operator+= ), 输入(operator>> ),输出(operator<< )

operator[]

operator[]是通过索引访问字符串中的字符它的使用和字符串的使用是一样的

#include <iostream>
#include<string>
using namespace std;
int main()
{string sl;sl = "hello\n";cout << sl[2] << endl;}

这段代码的结果是

e

也就是这串字符串的第二个字符但是有时候又感觉 [ ]不太高级这时候就有了库函数.at()

string:.at()

at.()与 [ ] 的区别是非常小的它的区别唯一可以说的便是它们的安全性问题例如

#include <iostream>
#include<string>
using namespace std;
int main()
{string sl;sl = "hello\n";cout << sl [10]<< endl;cout << sl.at(10) << endl;}

在这段代码中第一个代码可能会报错(编译器行为,cpp标准中 并没有规定报错如果报错只能说你的编译器比较新或者比较安全)但是第二行中就一定会报错(cpp标准规定报错)

operator+=

它这个和平时的+=的区别不大只不过它是作用于string的

#include <iostream>
#include<string>
using namespace std;
int main()
{string sl;sl = "hello";sl += "Linux";cout << sl << endl;}

它输出结果便是

hello Linux

同时它也时重载过的

operator>> ,输出(operator<< )

在我们使用的过程中流已经是非常常见但是它依旧是重载的

三、常见函数

在string的使用中有许多的函数下面我将写一些常见的string函数

string()

== string()是最最基础的的一个函数它的作用是创建一个字符串,如果是空就是空字符串,string(const char* s) 就是用C-string(c语言模式)来构造string类对象,string(size_t n, char c)就是string类对象中包含n个字符c, string(const string&s) 就是利用拷贝构造函数来创建字符串==
下面就来举个例子

#include <iostream>
#include <string> 
int main()
{string sl();string sl1("jiang");string sl2(5,'j');string sl3(sl1);cout << sl << endl;cout << sl1 << endl;cout << sl2 << endl;cout << sl3 << endl;return 0;
}

这些都是比较简单的用法但是比较重要

size()和length()

在C++的std::string类中,size()和length()函数实际上是等价的,它们都返回字符串中的字符数(不包括终止的空字符)。这两个函数的存在主要是出于兼容性和历史原因。(这里真的值得吐槽,string的设计实在是太复杂了有时间我会介绍一些)下面我将举个例子

#include <iostream>  
#include <string>  int main() {  std::string str = "Hello, world!";  std::cout << "String size: " << str.size() << std::endl;  std::cout << "String length: " << str.length() << std::endl;  return 0;  
}

empty ()

在C++的std::string类中,empty()是一个成员函数,用于检查字符串是否为空。当字符串不包含任何字符(即其长度为0)时,empty()函数返回true;否则,它返回false。

这个函数非常有用,因为它提供了一种简洁明了的方式来判断字符串是否已经被初始化或是否已经被清空

#include <iostream>  
#include <string>  int main() {  std::string str1; // 默认构造的字符串,长度为0  std::string str2 = "Hello, world!";  str2.clear(); // 清空字符串,使其长度为0  if (str1.empty()) {  std::cout << "str1 is empty." << std::endl;  } else {  std::cout << "str1 is not empty." << std::endl;  }  if (str2.empty()) {  std::cout << "str2 is empty." << std::endl;  } else {  std::cout << "str2 is not empty." << std::endl;  }  return 0;  
}

上述代码将输出:

str1 is empty.  
str2 is empty.

既然已经讲到检查清空了,那么就来说下清空函数clear

clear()

在C++的std::string类中,clear()是一个成员函数,用于移除字符串中的所有字符,使其变为空字符串。调用clear()后,字符串的长度将变为0,但它仍然是一个有效的std::string对象。

clear()函数的工作原理
clear()函数并不释放字符串所占用的内存空间(尽管某些实现可能会在内部进行优化,如重新分配内存以减少浪费),而是简单地将字符串的首字符设置为空字符(‘\0’,在C++的std::string实现中,这通常是通过修改内部表示字符串长度的变量来实现的,而不是实际地在内存中插入一个’\0’字符,因为std::string并不保证以空字符结尾)。因此,clear()操作通常是非常快速的。

#include <iostream>  
#include <string>  int main() {  std::string str = "Hello, world!";  std::cout << "Before clear: " << str << std::endl;  str.clear();  std::cout << "After clear: \"" << str << "\", size: " << str.size() << std::endl;  if (str.empty()) {  std::cout << "The string is now empty." << std::endl;  }  return 0;  
}

述代码将输出:

Before clear: Hello, world!  
After clear: "", size: 0  
The string is now empty.

reserve()和resize()

在string中虽然可以自动扩大但是如果字符太大或者刚好卡在扩容的边缘就非常难受,这时候我们就可以用reserve()或resize()

reserve()

reserve()函数用于预分配足够的内存空间来存储指定数量的字符,但不改变字符串的当前内容或长度。这个操作通常是为了提高性能,通过减少因字符串增长而发生的多次内存分配和复制操作。

当你知道将要向字符串中添加大量字符,并且希望避免在添加过程中发生多次内存重新分配时,可以使用reserve()来预留足够的空间。

std::string str;  
str.reserve(100); // 预留100个字符的空间  
str += "Hello, world!"; // 添加字符不会触发内存重新分配

在这个例子中,reserve(100)确保了字符串str有足够的空间来存储至少100个字符,而不会因添加"Hello, world!"这样的短字符串而触发内存重新分配。

resize()

resize()函数用于改变字符串的大小,即它可以增加或减少字符串中的字符数。如果新大小大于当前大小,那么新添加的字符将用指定的字符(默认为空字符’\0’)填充。如果新大小小于当前大小,那么字符串将被截断,超出新大小的字符将被移除。

std::string str = "Hello";  
str.resize(10, '*'); // 将字符串大小改为10,并用'*'填充新添加的位置  
// 现在str是"Hello*****"  str.resize(5); // 将字符串大小改回5,移除末尾的'*'  
// 现在str是"Hello"

begin()+ end()

在C++的std::string类中,begin()和end()是两个非常重要的成员函数,它们分别返回指向字符串开头和结尾的迭代器(迭代器我如果有时间也会详细讲解)。然而,将begin()和end()直接相加是没有意义的,也是不允许的。这两个函数返回的是不同类型的迭代器,它们代表了字符串中字符序列的起始和终止位置,但并不直接对应于数值,因此不能进行加法运算。

begin()

begin()函数返回一个指向字符串第一个字符的迭代器(或指向字符串开头位置的常量迭代器,如果函数被声明为const)。这个迭代器可以用于遍历字符串中的字符。

endl()

end()函数返回一个指向字符串最后一个字符之后位置的迭代器(或指向该位置的常量迭代器,如果函数被声明为const)。注意,这个迭代器并不指向字符串中的任何实际字符,而是指向字符串末尾的“假想”位置,通常用于表示字符串的结束。因此,你不能通过*(str.end())来访问字符串的最后一个字符;这样做会导致未定义行为。

std::string str = "Hello, world!";  
for (std::string::iterator it = str.begin(); it != str.end(); ++it){  //可以直接auto// 使用*it来访问当前字符  std::cout << *it;  
}

find() + npos()

在C++的std::string类中,find()和npos是两个与字符串搜索相关的成员函数和常量。这两个结合起来非常有用,就像是英雄和专武分开也能用但是加起来无敌。

find()

find()函数用于在字符串中搜索指定的字符或子字符串,并返回其第一次出现的位置的索引。如果未找到指定的字符或子字符串,则find()函数返回std::string::npos。

find()函数有多个重载版本,可以接受单个字符、C风格字符串(const char*)、std::string对象以及一个可选的搜索起始位置作为参数。

npos()

npos是std::string类中的一个静态常量,表示一个不可能的位置值。它通常用于指示未找到子字符串或字符的情况,或者作为某些函数(如find())的返回值,以表示搜索失败。

npos的值通常定义为std::string::size_type类型的最大值,这意味着它是一个非常大的数,远远超出了字符串可能达到的最大长度。

#include <iostream>  
#include <string>  int main() {  std::string str = "Hello, world!";  std::string search = "world";  std::size_t found = str.find(search);  if (found != std::string::npos) {  std::cout << "Found \"" << search << "\" at index " << found << std::endl;  } else {  std::cout << "\"" << search << "\" not found in the string." << std::endl;  }  return 0;  
}

nd()函数返回的索引是从0开始的,这意味着字符串的第一个字符的索引是0。npos的值通常非常大,因此在将find()的返回值与npos进行比较时,不需要担心整数溢出的问题。由于npos是std::string::size_type类型的,因此在使用它时应该确保与之比较的值也是相同类型的。

作者怨念

string的确非常好用也很超模但是它真的太杂了,几百个接口有很多接口都有重合并且有些名称并不是最好的,所以写string的文章要么写的不细要么写的像老太太臭脚布,作者已经写的很克制了但是还是写了两天总共写了5小时,哎,并且还埋了一些坑要填,他真的我哭死

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词