详解string

前⾯介绍了通过字符数组保存字符串,然后对字符数组中的字符串做各种操作为了更加方便,使字符串的操作更加简便并且强大,在C++中,又增加了 string 来处理字符串。

文章目录

  • 一、string的概念
  • 二、string的常见操作
    1. 创建字符串
    • 2.string字符串的输入
    1. cin的输入方式
    2. getline 的方式
    • 3.size()
    • 4.迭代器(iterator)
      • 1.begin()和end()
      • 2.正序遍历
      • 3.逆序遍历
    • 5.push_back()
    • 6.pop_back()
    • 7.insert
    • 8.find()
    • 9.substr()
    • 10.和string相关的函数
      • 1.stoi/stol
      • 2.stod/stof
    • 11.string的+=和+运算
  • 总结


一、string的概念

string 字符串其实是⼀种更加高级的封装, 符串的操作变得更加简单。 string 字符串中包含大量的方法,这些方法使得字 string 使用的好,慢慢你就不想使用字符数组来存放字符串了。

那到底什么是string呢?

而C++中将字符串直接作为⼀种类型,也就是 string 类型,使用 C++的字符串。 string 类型创建的对象就是C++的字符串。

string s1;  //空字符串
string s2 = "abc";

使⽤C++中提供的 string 时,必须添加头文件<string>

二、string的常见操作

我们想要具体了解的话,可以打开string - C++ 参考https://legacy.cplusplus.com/reference/string/string/

来了解string所有的内容。

1.创建字符串

string s1;                  //创建空字符串
string s2 = "hello world";  //创建字符串(常用)

代码展示:

#include <iostream>
#include <string>//添加string头⽂件

using namespace std;
int main()
{
	string s1;
	string s2 = "hello world";

	cout << "s1:" << s1 << endl;
	cout << "s2:" << s2 << endl;

	return 0;
}

运行结果:

string s1 表示创建空字符串,相当于创建整型 int a ,但未给 a ⼀个初始值。

string s2 = "hello world" 表⽰创建⼀个字符串s2,它的内容是" hello world ",要注意 s2 中的字符串不再以 \0 作为结束标志了。(C语言中的字符串是以 \0 作为结束标志的)。

简单的示意图是这样的:

值得注意的是:

上面这个图,仅仅是字符串s2的示意图,实际上 string 类型的字符串比这个要复杂的多, 更多的知识得学习C++的类和对象的知识才能明白。

当然C++中string创建的字符串和char类型数组所表示的字符串还有一个区别,string类型的字符串对象可以直接复制,比如:

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s1("hello world");
	string s2("hehe");

	s2 = s1;

	cout << s2 << endl;
	return 0;
}

运行结果如下:

2.string字符串的输入

        1.cin的输入方式

        可以直接用cin给string类型的字符串输入一个字符串类型的数据。

        代码如下:

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s;//输⼊

	cin >> s;//输出

	cout << s << endl;
	return 0;
}

        输入不带空格的字符串:

        输入带空格的字符串:

        这里我们可以发现,其实 cin 的方式给 string 类型的字符串中输入数据的时候,可以输入不带空格的字符串。但是如果带有空格,遇到空格也就读取结束了,没有办法正常读取,那怎么办呢?解决 办法就是使用getline 。

        2.getline 的方式

        getline 是C++标准库中的⼀个函数,用于从输入流中读取一行文本,并将其存储为字符串。         getline 函数有两种不同的形式,分别对应着字符串的结束方式。

1. istream& getline (istream& is, string& str);
2. istream& getline (istream& is, string& str, char delim);

        注意:getline 函数是输入流中读取一行文本信息,所有如果是在标准输入流(键盘)中读取数据,就可以传 cin 给第⼀个参数。

        • 第⼀种 getline 函数以换行符( '\n' )作为字符串的结束标志,它的⼀般格式是:

 getline(cin, string str)

 //cin -- 表⽰从输⼊流中读取信息
 
//str -- 是存放读取到的信息的字符串
 

        这种形式的getline函数输入流中读取文本,直到换行符(‘/n’)为止,然后读取到文本(不包括换行符)存储到指定string类型的变量str中。

        代码如下:

#include<iostream>
#include <string>

using namespace std;

int main()
{
	string name;
	getline(cin, name);
	cout << name << endl;

	return 0;
}

        运行结果如下:

        • 第⼆种 getline 函数允许用户自定义结束标志,它的⼀般格式是:

getline(cin, string str, char delim)

//cin -- 表⽰从输⼊流中读取信息
 
//str -- 是存放读取到的信息的字符串
 
//delim -- 是⾃定义的结束标志

        这种形式的getline函数从输入流中读取文本,直到读到用户定义的指定字符(delim)结束,然后将读取到的文本(不包括结束标志字符)存储到指定的string类型的变量str中。

        代码如下:

#include <iostream>
#include <string>
using namespace std;

int main() {

	string str;
	getline(cin, str, 'q');
	cout << str << endl;

	return 0;
}

        运行结果如下:

        我们可以发现,计算机在读取数据的时候,读到我们自定义的字符时,计算机会自动结束,并且不会读入我们定义的字符。

3.size()

string 中提供了 size() 函数用于获取字符串长度。

在C++中关于字符串的操作函数都是包含在string中的,所以调用和这些函数时,通常用 . 点运算符。

使用代码展示:
 

#include <iostream>
#include <string>  //添加string头⽂件    

using namespace std;



int main()
{
	string s;
	string s1 = "hello";
	string s2 = "hello world";
	string s3 = "12ab!~   ";

	cout << "s:" << s.size() << endl;
	cout << "s1:" << s1.size() << endl;
	cout << "s2:" << s2.size() << endl;
	cout << "s3:" << s3.size() << endl;

	return 0;
}

运行截图如下:

✅小提示: 前面我们学到的像,char 、 int 、 double 等内置类型的数据在操作的时候,不会使用 . 操作符的。

string 是C++提供的⼀种更加复杂的封装类型,在 string 类型的变量中加⼊了操作这 个字符串的各种方法(函数),比如求字符串长度、字符串末尾插⼊⼀个字符等操作。所以要对 string 类型的变量进行各种操作,就可以使用 . 操作符来使用这些函数。 我们可以看下面的例子,大家要仔细体会。

通过 size() 能获得字符串的长度,顺便就可以使用这个长度遍历字符串的,注意 string 类型的字符串是可以通过下标访问的,比如:

#include <iostream>

#include <string>

using namespace std;
int main()
{
	string s = "abcdef";
	int i = 0;

	for (i = 0; i < s.size(); i++)
	{
		cout << s[i] << " ";
	}

	return 0;
}

4.迭代器(iterator)

迭代器是⼀种对象,它可以用来遍历容器(比如我们现在学习的 string )中的元素,迭代器的作用类似于指针,或者数组下标。

这里要注意:访问迭代器指向的值,需要解引用(*)。

C++中的 string 提供了多种迭代器,用于遍历和操作字符串中的内容。这里给大家介绍⼀种最常 用的迭代器。

        1.begin( )和end( )

  • begin() :返回指向字符串第⼀个字符的迭代器,需要⼀个迭代器的变量来接收。 
  • end():返回指向字符串最后⼀个字符的下⼀个位置的迭代器(该位置不属于字符串)。
  • string中begin()和end()返回的迭代器的类型是 string :: iterator 。      
string s = "abcdef";

        小提示:

  • 迭代器是可以进行大小比较,也可以进行 + 或者 - 整数运算的。 比如: it++ ,就是让迭代器前进⼀步, it-- 就是让迭代器退后⼀步。
  • 同⼀个容器的两个迭代器也可以相减,相减结果的绝对值,是两个迭代器中间元素的个数。

        代码演示如下:

#include <iostream>
#include <string>

using namespace std;

int main() {
	string s = "abcdef";
	string::iterator it1 = s.begin();
	string::iterator it2 = s.end();

	cout << (it1 < it2) << endl;
	cout << it1 - it2 << endl;
	return 0;
}

        运行结果如下:

        我们可以发现,begin()对应的下标确实比end()对应的下标小,所以结果显示1为真。

        正序遍历

        迭代器通常用于遍历字符串的,可以正序遍历,也可以逆序遍历。

        代码如下:

#include <iostream>
#include <string>

using namespace std;


int main()
{
	string s = "abcdef";
	for (string::iterator it = s.begin();it != s.end();it++) {
		cout << *it << ' ';
	}


	return 0;


}

        运行结果如下:

        当我们不知道It的返回类型的时候用auto运行起来也是一样的。

#include <iostream>
#include <string>

using namespace std;


int main()
{
	string s = "abcdef";
	/*for (string::iterator it = s.begin();it != s.end();it++) {
		cout << *it << ' ';
	}*/
	for (auto it = s.begin();it != s.end();it++) {

		cout << *it << ' ';
	}

	return 0;


}

        逆序遍历

        代码如下:

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s = "abcdef";

	for (string::iterator it = s.end() - 1; it >= s.begin(); --it)
	{
		cout << *it << ' ';
	}

	return 0;
}

                运行结果如下:

        这里要注意一点:通过迭代器找到元素后,改变迭代器指向的元素,是可以直接改变字符串内容的。

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string str = "abcdef";
	cout << str << endl;
	for (string::iterator it = str.begin(); it != str.end(); ++it)
	{
		*it = 'x';
	}
	cout << str << endl;
	return 0;
}

        运行结果如下:

5.push_back()

push_back() 用于在字符串尾部插⼀个字符。

例如:

代码演示:

#include <iostream>
#include<string> //添加string头⽂件


using namespace std;


int main()
{
	//向空字符串中尾插字符

	string s;
	s.push_back('h');
	s.push_back('e');
	s.push_back('l');
	s.push_back('l');
	s.push_back('o');
	cout << s << endl;
	//向非空字符串中尾插字符

	string s1 = "hello ";
	s1.push_back('w');
	s1.push_back('o');
	s1.push_back('r');
	s1.push_back('l');
	s1.push_back('d');
	cout << s1 << endl;
	////批量插⼊字符

	string s2;
	for (char c = 'a'; c <= 'f'; c++)
	{
		s2.push_back(c);
	}
	cout << s2 << endl;
	return 0;
}

运行结果如下:

6.pop_back()

pop_back() 用于删除字符串中尾部的⼀个字符。这个成员函数是在 C++11 标准中引用的,部分编译器可能不支持。

pop_back() 的作用是用于删除字符串最后一个字符。

代码如下:

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s = "hello";
	cout << "s:" << s << endl;
	//尾删

	s.pop_back();
	cout << "s:" << s << endl;
	//尾删

	s.pop_back();
	cout << "s:" << s << endl;


	return 0;
}

运行结果如下:

值得注意的是:当字符串中没有存储字符即为空字符串时,使用 pop_back() 可能会报错,会出现程序崩溃的问题。

如何解决这个问题呢?

来看接下来这段代码:

#include <iostream>
#include<string>    //添加头文件<string>


using namespace std;

int main()
{
	string s = "abc";
	{
		while (s.size() > 0)  //通过size()函数来控制字符串的⻓度
		{ 
			s.pop_back();
		}
	 
	
	return 0;
}

我们调用s.size()函数来解决空字符问题,防止报错。

7.insert

如果我们需要在字符串中间的某个位置插入一个字符串,怎么办呢?这时候我们得掌握⼀个函数就是 insert

函数原型如下:

1.string& insert (size_t pos, const string& str); //pos位置前⾯插⼊⼀个string字符串
2.string& insert (size_t pos, const char* s); //pos位置前⾯插⼊⼀个C⻛格的字符串
3.string& insert (size_t pos, size_t n, char c);//pos位置前⾯插⼊n个字符c
 

代码演示如下:

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s = "abcdefghi";
	string str = "xxx";
	cout << s << endl;

	s.insert(3, str);

	cout << s << endl;

	return 0;
}

运行结果如下:

代码还可以这样写:

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s = "abcdefghi";
	cout << s << endl;

	s.insert(3, "xxx");

	cout << s << endl;
	return 0;
}
#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s = "abcdefghi";
	cout << s << endl;

	s.insert(3, 3, 'x');

	cout << s << endl;
	return 0;
}

前一个3代表的是下标的位置,第二个3代表的是插入几个‘x’字符。

8.find()

find() 函数用于查找字符串中指定子串/字符,并返回子串/字符在字符串中第⼀次出现的位置。

例如要找一个字符串 'lo' ,在字符串 'hello world hello C++' 中第一个 'lo'出现的位置是下标为2的位置,所以返回值就是2。

1.size_t find (const string& str, size_t pos = 0) const;
//查找string类型的字符串str,默认是从头开始查找,pos可以指定位置开始

2.size_t find (const char* s, size_t pos = 0) const;
//查找C⻛格的字符串s,默认是从头开始查找,pos可以指定位置开始
 
3.size_t find (const char* s, size_t pos, size_t n) const;
//在字符串的pos这个位置开始查找C⻛格的字符串s中的前n个字符

4.size_t find (char c, size_t pos = 0) const;
//查找字符c,默认是从头开始,pos可以指定位置开始

返回值:

  • 若找到,返回子串/字符在字符串中第⼀次出现的起始下标位置。
  • 若未找到。返回⼀个整数值 的返回值是否等于 npos 。通常判断 find()函数返回值是否等于 npos 就能知道是否查找到子串或者字符。

代码如下:

#include <iostream>
#include <string>    
using namespace std;
//添加string头⽂件

int main()
{
	string s = "hello world hello everyone";
	string str = "llo";
	//查找string类型的字符串

	size_t n = s.find(str);
	cout << n << endl;
	n = s.find(str, n + 1); //从n + 1这个指定位置开始查找

	cout << n << endl;
	//查找C⻛格的字符串

	n = s.find("llo");
	cout << n << endl;
	n = s.find("llo", n + 1); //从n + 1这个指定位置开始查找

	cout << n << endl;
	return 0;
}

运行结果如下:

代码如下:

#include <iostream>
#include <string>    
using namespace std;


int main()
{
	string s = "hello world hello everyone";

	size_t n = s.find("word", 0, 3);	//在s中,0这个指定位置开始查找"word"中的前3个字符
	cout << n << endl;

	n = s.find("everyday", n + 1, 5);
	cout << n << endl;
		return 0;
}

运行结果如下:

代码如下:

#include <iostream>
#include <string>    
using namespace std;


int main()
{
	string s = "hello world hello everyone";

	size_t n = s.find('o');

	cout << n << endl;
	n = s.find('o', n + 1);

	cout << n << endl;
	return 0;
}

运行结果如下:

当然也有找不到的情况:

代码如下:

#include <iostream>
#include <string>    
using namespace std;

int main()
{
	string s = "hello world hello everyone";
	string str = "bit";
	size_t n = s.find(str);
	cout << n << endl;

	if (n != string::npos)
		cout << "找到了,位置是:" << n << endl;
	else
		cout << "没有找到" << endl;

		return 0;
}

运行结果如下:

我们发现有一个很大的数值,这个就是nops默认的值。

9.substr()

substr() 函数用于截取字符串中指定位置指定长度的子串。函数原型如下:

1.string substr (size_t pos = 0, size_t len = npos) const;

2.//pos 的默认值是0,也就是从下标为0的位置开始截取

3.//len 的默认值是npos,意思是⼀直截取到字符串的末尾
 
 

substr() :如果函数不传参数,就是从下标为0的位置开始截取,直到结尾,得到的是整个字符串;

substr(pos) :从指定下标 pos 位置开始截取子串,直到结尾;

substr(pos, len) :从指定下标 pos 位置开始截取⻓度为 len 的子串。

如图所示

返回值类型: string ,返回的是截取到的字符串,可以使用 string 类型的字符串接收。

代码如下:

#include <iostream>
#include<string>    


using namespace std;
int main()
{
	string s = "hello world hello everyone";
	string s1 = s.substr(7);
	cout << s1 << endl;
	string s2 = s.substr(7, 6);
	cout << s2 << endl;
	return 0;
}

运行结果如下:

注意,substr()函数经常和find()函数配合使用,find()负责找到具体位置,substr()负责从这个位置向后获得字符串。

代码如下:

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string s = "hello world hello everyone";

	size_t n = s.find("world");
	string s2 = s.substr(n, 10);
	cout << s2 << endl;


	return 0;
}

运行结果如下:

10.和string相关的函数

        1.stoi/stol

        stoi是将字符串转成int类型的值

        stol是将字符串转long int类型的值

        这两个函数非常类型,这里以 stoi 为例讲解⼀下这⾥函数的使用方式。

        stoi 函数其实可以将⼀个 string 类型的字符串,转化为整型,函数原型如下:

1. int stoi (const string&  str, size_t* idx = 0, int base = 10);
2. long stol (const string&  str, size_t* idx = 0, int base = 10);

        参数的解读:

  • str 表示被转换的 string 类型的字符
  • idx 是⼀个输出型参数,也就是这个通过这个参数会带回⼀个值。idx 是⼀个指针,需要在外边创建⼀个 size_t 类型的值,传递它的地址给 idx ,这个参数将会带回 str 中无法正确匹配数字的第⼀个字符的位置。
  • base 表示被解析的字符串中数字的进制值,可能是2,8,10,16或者0.

        默认情况下这个值是 10 ,表示 10 进制数字

        如果传递的是 2 ,表示被解析的字符串中是 2 进制的数字,最终会转换成 10 进制

        如果传递的是 8 ,表示被解析的字符串中是 8 进制的数字,最终会转换成 10 进制

        如果传递的是 16 ,表示被解析的字符串中是 16 进制的数字,最终会转换成 10 进制

        如果传递的是 0 ,会根据字符串的内容的信息自动推导进制,比如:字符串中有0x,就认为是 16 进制,, 0 开头会被认为是 8 进制,最终会转换成 10 进制。

        代码演示:

#include <iostream>
#include<string>   

using namespace std;

int main()
{
	size_t pos = 0;
	string s1 = "11x34";
	int ret1 = stoi(s1, &pos, 16);
	cout << ret1 << endl;

	cout << "pos:" << pos << endl;

	string s2 = "11x34";
	int ret2 = stoi(s2, &pos, 2);
	cout << ret2 << endl;

	cout << "pos:" << pos << endl;

	string s3 = "0x11x34";
	int ret3 = stoi(s3, &pos, 0);

	cout << ret3 << endl;

	cout << "pos:" << pos << endl;
	return 0;
}

        运行结果:

        2.stod/stof

        stod 是将字符串转换成 double 类型的值,函数原型如下,和 stoi 函数的比较的话,少了描述字符串中数字进制的参数,其他参数⼀致。stof 是将字符串转换成 flaot 类型的值。

函数原型如下:

1 double stod (const string&  str, size_t* idx = 0);
2 float stof (const string&  str, size_t* idx = 0);

代码如下:

 #include <iostream>
 #include<string>    
using namespace std;
 int main()
 {
 string s = "3.14x456";
 double ret = stod(s, NULL);
 cout << ret << endl;
 return 0;
 }

运行结果如下:

11.string的+=和+运算

前面讲的push_back() 是用于在字符串后添加⼀个字符,然而部分情况下我们需要向原有的字符串后继续添加字符串。

其实 string 类型的字符串是支持 + 和 += 运算的。这里的本质是 string 中重载了operator+= 这个操作符。

例如:hello 后面要添加 world 这个单词。

我们用具体的代码实现一下:

代码如下:

运行结果如下:


总结

感谢各位的观看与借鉴,这是总结的关于string常用的一些功能,学会这些功能,对字符串的理解就更深了,祝愿我们共同进步。

这里文章就讲完啦,记得点赞 + 关注哦 ❤。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值