重生之我在21世纪学C++—string
一、string 概念
string 字符串是一种更加高级的封装,string 字符串中包含大量的方法,这些方法可以使得字符串的操作变得更加简单。如果 string 使用的好,慢慢你就不想使用字符数组来存放字符串了,因为更简单嘛。
C++ 将字符串直接作为一种类型,也就是 string 类型,使用 string 类型创建的对象就是 C++ 的字符串。
使用 C++ 中提供的 string 时,必须添加头文件 <string> 。
二、string 常见操作
1、创建字符串
方式 | 解释 |
string s1; | 创建空字符串 |
string s2 = "hello world"; | 创建一个内容为“hello world”的字符串(常用) |
string s3("hello world"); | 创建一个内容为“hello world”的字符串 |
string s4 = s2; | 用一个现成的字符串 s2 ,初始化另一个字符串 s4 |
(1)string s1 表示创建空字符串,相当于创建整型 int a,但未给 a 一个初始值。
(2)string s2 = "hello world" 表示创建一个字符串 s2,它的内容是 "hello world",需要注意的是 s2 中的字符串不再以 \0 作为结束标志了。(C 语言中的字符串是以 \0 作为结束标志的)
(3)C++中的 string 创建的字符串和 char 类型的数组所表示的字符串有一个区别, string 类型的字符串对象是可以直接赋值的。
2、string 字符串的输入
(1) cin 的方式
可以直接使用 cin 给 string 类型的字符串中输入一个字符串的数据。
这里我们可以发现,其实用 cin 的方式给 string 类型的字符串中输入数据,可以输入不带空格的字符串,此时一切正常。但是如果是带有空格的字符串,当遇到空格时读取就结束了,所以此时就没有办法正常读取里。如果想要读取带有空格的字符串,这个时候就要使用 getline 函数了。
(2) getline 的方式
getline 是 C++ 标准库中的一个函数,用于从输入流中读取一行文本,并将其存储为字符串。
getline 函数有两种不同的形式,分别对应读取字符串的两种情况。
istream& getline (istream& is, string& str);
istream& getline (istream& is, string& str, char delim);
istream 是输入流类型,cin 是 istream 类型的标准输入流对象。
ostream 是输出流类型,cout 是 ostream 类型的标准输出流对象。
getline 函数是从输入流中读取一行文本信息,所有如果是在标准输入流(键盘)中读取数据,就可以传 cin 给第一个参数。
1)第一种 getline 函数以换行符( '\n' )作为字符串的结束标志,它的一般格式是:
getline(cin, string str);
// cin 表示从标准输入流中读取信息;
// str 是存放读取到的信息的字符串;
这种形式的 getline 函数是从输入流(例如标准输入流 cin)中读取数据,直到遇到换行符('\n')为止,然后将读取到的文本(不包括换行符)存储到指定的 string 类型的变量 str 中。
2)第二种 getline 函数允许用户自定义结束标志,它的一般格式是:
getline(cin, string str, char delim);
//cin 表示从标准输入流中读取信息
//str 是存放读取到的信息的字符串
//delim 是自定义的字符串读取结束标志
这种形式的 getline 函数是从输入流中读取数据,直到遇到用户指定的结束标志字符( delim )停止读取,然后将读取到的文本(不包括结束标志字符)存储到指定的 string 类型变量 str 中。
3、size()
string 中提供了 size() 函数用于获取字符串长度。
在C++中关于字符串的操作函数都是包含在 string 中的,所以调用这些函数时,需要用 . 点运算符。
4、迭代器(iterator)
迭代器是一种对象,它可以用来遍历容器(比如我们现在学习的 string )中的元素,迭代器的作用类似于指针,或者数组下标。访问迭代器指向的值,需要解引用(*)。
C++ 中的 string 提供了多种迭代器,用于遍历和操作字符串中的内容。这里给大家介绍一种最常 用的迭代器:begin() 和 end()。
begin() : 返回指向字符串第一个字符的迭代器,需要用一个迭代器变量来接收。
end() : 返回指向字符串最后一个字符的下一个位置的迭代器(该位置不属于字符串)。
string 中 begin() 和 end() 返回的迭代器的类型是 string::iterator 。
迭代器是可以进行大小比较的,也可以进行 + 或者 - 整数运算。
比如:it++,就是让迭代器前进一步,it-- 就是让迭代器退后一步。
同一个容器的两个迭代器也可以相减,相减结果的绝对值,是两个迭代器中间元素的个数。
使用迭代器打印数组元素:
正序遍历:
逆序遍历:
通过迭代器找到元素后,改变迭代器指向的元素,是可以直接改变字符串内容的。
5、push_back()
push_back() 用于在字符串尾部插一个字符。
6、字符串的 += 和 + 运算
push_back () 是用于在字符串末尾添加一个字符,然而部分情况下我们需要向原有的字符串末尾继续添加字符串。
我们需要知道的是 string 类型的字符串是支持 + 和 += 运算的。这里的本质是 string 中重载了 operator+= 这个操作符。
7、pop_back()
pop_back() 用于删除字符串尾部的一个字符。这个成员函数是在 C++11 标准中引入的,所以有的编译器可能不支持。
注意:当字符串中没有字符的时候,即为空字符串,此时如果调用 pop_back() ,程序会出现异常,因为这种行为是标准未定义行为,要避免这么使用。所以不可对空字符串继续进行pop_back()操作。
8、insert
如果我们需要在字符串中间的某个位置插入一个字符串,这是就要使用 insert() 函数了。
函数原型如下:
string& insert (size_t pos, const string& str);
//在pos位置前面插入一个string字符串
string& insert (size_t pos, const char* s);
//在pos位置前面插入一个C语言风格的字符串
string& insert (size_t pos, size_t n, char c);
//pos位置前面插入 n 个字符 c
1)
2)
3)
9、find()
find() 函数用于查找字符串中指定子串或字符,并返回子串或字符在字符串中第一次出现的位置。
size_t find (const string& str, size_t pos = 0) const;
//查找string类型的字符串str,默认是从头开始查找,但是也可以通过输入一个值pos从指定位置开始查找
size_t find (const char* s, size_t pos = 0) const;
//查找C风格的字符串s,默认是从头开始查找,但是也可以通过输入一个值pos从指定位置开始查找
size_t find (const char* s, size_t pos, size_t n) const;
//在字符串的pos这个位置开始查找C风格的字符串s中的前n个字符,
size_t find (char c, size_t pos = 0) const;
//查找字符c,默认是从头开始,但是也可以通过输入一个值pos从指定位置开始查找
返回值:
1)若找到,则返回子串或字符在字符串中第一次出现的起始下标位置。
2)若未找到,返回一个整数值 npos 。一般通过 find () 函数的返回值是否等于 npos 来判断是否查找到子串或者字符。
(1)查找string类型的字符串str、
(2)查找C风格的字符串s
(3)查找C风格的字符串s中的前n个字符
(4)查找字符c
(5)查找不到的情况
在字符串中查找字符或者字符串时,有可能查找不到,这时候 find 函数会返回 npos 这个值,该数字并不是一个随机的数字,而是 string 中定义的一个静态常量 npos 。一般通过 find () 函数的返回值是否等于 npos 来判断是否查找到子串或者字符。
static const size_t npos = -1;
注意:npos 是 string 中定义的,使用 npos 需要带上 string:: 指明是string类中的。
10、substr()
substr() 函数用于截取字符串中指定位置指定长度的子串。函数原型如下:
string substr (size_t pos = 0, size_t len = npos) const;
//pos 的默认值是0,也就是从下标为0的位置开始截取
//len 的默认值是 npos,意思是从pos位置一直截取到字符串的末尾
substr () : 如果函数不传参数,就是从下标为 0 的位置开始截取,直到结尾,得到的是整个字符串,相当于直接打印整个字符串;
substr (pos) :从指定下标 pos 位置开始截取子串,直到结尾;
substr (pos, len) :从指定下标 pos 位置开始截取长度为 len 的子串。
返回值:
类型是 string ,返回的是截取到的字符串,可以使用 string 类型的字符串接收。
11、string 的关系运算
C++ 中为 string 提供了一系列的关系运算。
字符串的比较是基于字典序进行的,比较是对应位置上字符的ASCII值的大小,比较的不是字符串的长度。
例如:
"abc" < "aq" // 'b' 的ASCII码值是小于 'q' 的
"abcdef" < "ff" // 'a' 的ASCII码值是小于 'f' 的
"100" < "9" // '1' 的ASCII码值是小于 '9' 的
需要注意的是,关系运算的双方中至少要有一个 string 风格的字符串,可以有C语言风格的字符串,但是不能对两个C语言风格的字符串进行关系运算。
12、和 string 相关的函数
(1)stoi / stol
stoi 是将字符串转换成 int 类型的值。
stol 是将字符串转换成 long int 类型的值。
函数原型如下:
int stoi (const string& str, size_t* idx = 0, int base = 10);
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。
1)默认情况下这个值是 10,表示 10 进制数字。
2)如果传递的是 2,表示被解析的字符串中是 2 进制的数字,最终会被转换成 10 进制。
3)如果传递的是 8,表示被解析的字符串中是 8 进制的数字,最终会被转换成 10 进制。
4)如果传递的是 16,表示被解析的字符串中是 16 进制的数字,最终会被转换成 10 进制。
5)如果传递的是 0,会根据字符串的内容的信息自动推导进制,比如:字符串中有 0x,就认为是 16 进制,0 开头会被认为是 8 进制,最终会转换成 10 进制。
(2)stod / stof
stod 是将字符串转换成 double 类型的值,和 stoi 函数相比较,少了描述字符串中数字进制的参数,其他参数完全一致。 stof 是将字符串转换成 float 类型的值。函数原型如下:
double stod (const string& str, size_t* idx = 0);
float stof (const string& str, size_t* idx = 0);
(3)to_string
函数原型如下:
string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);
to_string() 函数可以将数字转换成字符串,从上述函数原型的角度来看的话,该函数可以将整型、浮点型的数字转换成字符串。