【C++】string的使用【上】
目录
- 一、`string`类
- 1.1 创建字符串
- 1.2 `string`字符串的输入
- 1.2.1 `cin`的方式
- 1.2.2 `getline`的方式
- 1.3 `size()`
- 1.4 `operator[]`
- 1.5 迭代器`iterator`
- 1.5.1 `begin()`和`end()`
- 1.5.2 使用迭代器遍历
- 1.5.3 使用迭代器更改元素数据
- 1.6 `push_back()`
- 1.7 字符串的`+=`和`+`运算
- 1.8 `pop_back()`
- 1.9 `insert()`
- 1.10 `find()`
个人主页<—请点击
C++专栏<—请点击
一、string
类
在C++
中,string
是标准库提供的一个类(class)
,它位于<string>
头文件中,全称为 std::string
。它是C++
标准模板库(STL)
的一部分,用于处理和操作字符串。
string
字符串中包含大量的方法,这些方法使得字符串的操作变得更加简单。
string
的相关操作:请点击—>string
1.1 创建字符串
//创建空字符串
string s1;
//常用创建方式
string s2 = "hello world";
string s1
表示创建空字符串,相当于创建整型int a
,但未给a
⼀个初始值。
string s2 = "hello world"
表示创建⼀个字符串s2
,它的内容是"hello world"
,要注意s2
中的字符串不再以\0
作为结束标志了。(C 语言中的字符串是以\0作为结束标志的)。
使用时不要忘记加头文件<string>
。第二种创建方式实际上在之前的博客中讲过,是构造加拷贝构造,但在目前的新编译器上运行会优化成直接构造,这里就不再过多赘述了。
除此之外,还可以进行如下创建方式,和我们在之前博客中讲类和对象时相同:
string s2 = "hello world";
string s3("hello new world");
string s4 = s3;
s3 = s2;
1.2 string
字符串的输入
1.2.1 cin
的方式
#include <iostream>
#include <string>
using namespace std;
int main()
{string s;cin >> s;cout << s << endl;return 0;
}
这就是cin
输入string
字符串的方式,那我们用了不带空格的输入,那我们再尝试一下带空格的输入吧!
这里我们可以发现,其实cin
的方式给string
类类型的字符串中输入数据的时候,可以输入不带空格的字符串。但是如果带有空格,遇到空格也就读取结束了,没有办法正常读取,这里和C语言
的scanf
很是类似,但C语言
是有解决办法的,那C++
中的解决方案是什么呢? 那就是getline
。
1.2.2 getline
的方式
getline
是C++
标准库中的⼀个函数,用于从输入流中读取一行文本,并将其存储为字符串。getline
函数有两种不同的形式,分别对应着字符串的结束方式:
istream
是输入流类型,cin
是istream
类型的标准输入流对象。
ostream
是输出流类型,cout
是ostream
类型的标准输出流对象。这里我们在之前博客重载>>、<<
时已经接触过了。
getline
函数是输入流中读取一行文本信息,所有如果是在标准输入流(键盘)
中读取数
据,就可以传cin
给第⼀个参数。
那此时之前的代码就可以变成这样:
第一种
:
string s;
getline(cin, s);
cout << s << endl;
第⼀种getline
函数以换行符'\n'
作为字符串的结束标志,它的⼀般格式是getline(cin, string str)
。它读取到的文本不包含换行符'\n'
。
第二种
:
string s;
getline(cin, s, 'r');
cout << s << endl;
第二种getline
函数允许用户自定义结束标志,它的⼀般格式是:getline(cin, string str, char delim)
。它读到的文本不包括用户指定的结束标志字符'delim'
。
1.3 size()
string
中提供了size()
函数用于获取字符串长度。在C++
中这些操作函数都包含在类中,所以调用时用'.'
访问。
string s;
s = "hello world!";
cout << s.size() << endl;
1.4 operator[]
string
类中添加了[]
的运算符重载,所以我们直接可以用下标访问string
类对象中存储的元素。
string s;
s = "hello world!";
cout << s.size() << endl;
for (int i = 0;i < s.size();i++)
{cout << s[i] << " ";
}
cout << endl;
1.5 迭代器iterator
迭代器是⼀种对象,它可以用来遍历容器中的元素,迭代器的作用类似于指针,或者数组下标。不过访问迭代器指向的值,需要解引用*
。
1.5.1 begin()
和end()
这两个是比较常用的迭代器。
begin()
:返回指向字符串第⼀个字符的迭代器,需要⼀个迭代器的变量来接收。
end()
:返回指向字符串最后⼀个字符的下⼀个位置的迭代器(该位置不属于字符串)
。
string
中begin()
和end()
返回的迭代器的类型是string::iterator
。
迭代器是可以进行大小比较,也可以进行+
或者-
整数运算的。例如:it++
,就是让迭代器前进⼀步,it--
就是让迭代器退后⼀步。
同⼀个容器的两个迭代器也可以相减,相减结果的绝对值,是两个迭代器中间元素的个
数。
使用:
string s("hello world!");
string::iterator it1 = s.begin();
string::iterator it2 = s.end();
cout << (it1 < it2) << endl;
cout << it1 - it2 << endl;
cout << it2 - it1 << endl;
这里的string::iterator
这个类型太长了,到用的时候记不住怎么办呀,不要着急,C++
中有个关键字auto
,它是类型推导关键字,它允许编译器根据初始化表达式自动推断变量的类型。我们可以通过一些代码来了解一下:
auto x = 10;
auto y = 3.14;
cout << x << endl;
cout << y << endl;
它会自动推导出类型。注意:auto
变量必须在定义时初始化,否则无法推导类型。
特殊情况1:
int x = 10;
int& z = x;
auto g = z;
g++;
cout << g << endl;
cout << z << endl;
这里的g
是int
类型,而不是int&
类型,从g
的值变化后z
不变就可以看出。如果要变成int&
就要在auto
后加上&
。
此时:
特殊情况2:
int x = 10;
auto y = &x;
auto* z = &x;
这里的y
和z
都指向x
都是int*
类型。
好了,了解了auto
关键字,我们再回到主线上来,那我们之前相关迭代器iterator
可以转换为:
string s("hello world!");
auto it1 = s.begin();
string::iterator it2 = s.end();
cout << (it1 < it2) << endl;
cout << it1 - it2 << endl;
cout << it2 - it1 << endl;
这里只更换了一个,可以都更换。
1.5.2 使用迭代器遍历
遍历:
string s("hello world!");
for (auto i = s.begin();i < s.end();i++)
{//访问迭代器指向的值 ,需要解引用*cout << *i << " ";
}
cout << endl;
在遍历这里呢,C++
中有一块语法糖,就是范围for
,它是C++ 11
标准引入的新特性,它的底层就是用迭代器完成的,所以在这里提它,像vector、list、map
等标准容器都定义了自己的迭代器,范围 for 循环
会自动使用这些迭代器。
我们来看一下如何使用:
string s("hello world!");
for (auto i : s)
{cout << i << " ";
}
cout << endl;
范围for
的优势:
- 自动取容器数据,赋值给
i
- 自动判断结束
- 自动迭代
真不戳~
注意
:范围for
是C++11
特性新引入的,在平台DevC++ 5.11
默认是会产生编译错误的,处理方法如下:
1、在上方工具栏中点击编译选项。
2、在第一个窗口处添加-std=c++11
,然后勾选编译时加入以下命令
,点击确定,就可以使用了。
1.5.3 使用迭代器更改元素数据
我们可以像之前那样使用普通for
循环,更改操作:*i='delim';
,这里我们用范围for
演示:
string s("hello world!");
for (auto& i : s)
{i = 'X';
}
for (auto i : s)
{cout << i << " ";
}
cout << endl;
注意:使用范围for
时,第一个必须是auto&
才能更改s
中的数据。
1.6 push_back()
push_back()
用于在字符串尾部插⼀个字符。使用时记得添加头文件<string>
。
使用:
string s("hello ");
cout << s << endl;
s.push_back('w');
s.push_back('o');
s.push_back('r');
s.push_back('l');
s.push_back('d');
s.push_back('!');
cout << s << endl;
1.7 字符串的+=
和+
运算
C++
的string
类中重载了operator+=
和operator+
。
它们均支持两个类型,至少有一个string
类型的+
和+=
操作。
'+'
使用:
string s("hello");
s = s + " world";
cout << s << endl;string s1("hello");
s1 = " world" + s1;
cout << s1 << endl;string s3("hello");
string s4(" world");
s3 = s3 + s4;
cout << s3 << endl;string s5("hello");
s5 = s5 + 'a';
cout << s5 << endl;string s6("hello");
s6 = 'a' + s6;
cout << s6 << endl;
'+='
使用:
string s("hello ");
string s1("world!");
s += s1;
cout << s << endl;string s2("hello ");
s2 += "world!";
cout << s2 << endl;string s3("hello ");
s3 += 'g';
cout << s3 << endl;
1.8 pop_back()
pop_back()
用于删除字符串中最后一个字符。这个成员函数是在C++11
标准中引入的,有的编译器可能不支持。例如:DevC++ 5.11
,处理方法和上面讲的相同。
使用:
string s("hello");
cout << s << endl;
s.pop_back();
cout << s << endl;
s.pop_back();
cout << s << endl;
注意
:但是当字符串中没有字符的时候,再调用pop_back()
时,程序会出现异常。这种行为也是标准未定义的行为,要避免这样使用。
string s;
s.pop_back();
cout << s << endl;
以上代码,在vs2022
上运行时程序崩溃了。
如果要全部删除,可借助size()
函数进行。
使用:
string s("woc");
cout << s << endl;
while (s.size() > 0)
{s.pop_back();
}
cout << s << endl;
1.9 insert()
如果我们需要在字符串中间的某个位置插入一个字符串,该怎么办呢?这时候我们得掌握一个函数就是insert()
。
insert
函数有很多个函数接口,如上图所示,但最常用的是下面的:
使用示意图:
使用1
:
string s("hello world!");
string s1("new ");
cout << s << endl;
s.insert(6, s1);
cout << s << endl;
使用2
:
string s("hello world!");
cout << s << endl;
s.insert(6, "new ");
cout << s << endl;
使用3
:
string s("hello world!");
cout << s << endl;
s.insert(0, 3, 'o');
cout << s << endl;
1.10 find()
find()
函数用于查找字符串中指定子串/字符
,并返回子串/字符
在字符串中第一次出现的位置。
返回值:
- 如果找到,返回第一次出现的起始下标位置。
- 如果没找到,返回返回整数
npos
,一个很大的数字。
注意
:通常判断find()
函数的返回值是否等于npos
就能知道是否查找到子串或者字符。
使用:
string s("hello world!");
string s1("llo");
size_t pos = s.find(s1, 0);
cout << pos << endl;
查找前n
个字符:
string s("hello new world!");
size_t pos = s.find("news", 0, 3);
//从0的位置开始找,查找前3个字符"new"
cout << pos << endl;
查找字符c
:
string s("hello new world!");
size_t pos = s.find('e', 0);
cout << pos << endl;
查找所有出现的位置:
string s("hello new world!");
size_t pos = s.find('e', 0);
while (pos != string::npos)
{cout << pos << " ";pos = s.find('e', pos+1);
}
cout << endl;
总结:
以上就是本期博客分享的全部内容啦!如果觉得文章还不错的话可以三连支持一下,你的支持就是我前进最大的动力!
技术的探索永无止境! 道阻且长,行则将至!后续我会给大家带来更多优质博客内容,欢迎关注我的CSDN账号,我们一同成长!
(~ ̄▽ ̄)~