自学内容网 自学内容网

认识string(一)详解


感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接
🐒🐒🐒 个人主页
🥸🥸🥸 C语言
🐿️🐿️🐿️ C语言例题
🐣🐣🐣 python
🐓🐓🐓 数据结构C语言
🐔🐔🐔 C++
🐿️🐿️🐿️ 文章链接目录

标准库中的string类

了解如何看文档

string文档(这个文档广告有点多)
建议在看这个文档的时候用旧版本去看,因为旧版本支持搜索,想要进去旧版本就点击红色方框这个位置
在这里插入图片描述
如果英语不好的可以点击翻译当前页面,但是有时候翻译会有一点问题,比如我们搜索printf函数,然后翻译当前页面后,就会出现下面这种情况,参数的说明符被翻译了
在这里插入图片描述
而没有被翻译时是这样的
在这里插入图片描述
所以最好是用英语去看

C++的STL的容器是在reference的containers中
在这里插入图片描述
在这里插入图片描述
string则是在reference的miscellaneous headers,如果sting实在是不想找也可以通过搜索去查找
在这里插入图片描述
在这里插入图片描述
我们点击Class instantiations的string看看
在这里插入图片描述
这个页面中
Member types是指成员类型

Member functions是指成员函数,也就是前面类和对象所指的六个默认成员函数,因为六个当中有两个不是很重要,所以这部分只有四个,而因为构造和拷贝构造都是构造,所以将他们归纳在一起

Iterators是迭代器,后面会讲

Capacity是容量,这个听起来很抽象,容量不知道是什么东西,举个例子,数据结构中会涉及到扩容等功能,容量其实表示的就是他的内存,因为string是个字符顺序表,所以会出现扩容

Element access翻译是元素访问,这个就有点类似数组访问他的元素

Modifiers翻译是修饰语,其中operator+=是我们比较熟悉的
在这里插入图片描述
他给的例子是这样的,可能就是用string修饰name和family,然后用+=的方式在后面加字符串
在这里插入图片描述
String operations翻译是字符串操作,看了一下他这个部分的函数,可能就是对字符串进行拷贝,还有查找字符串中的某个字符…这些操作

Member constants的翻译是成员常量,这个部分只有一个npos,这个npos是静态常量,他的大小为-1

Non-member function overloads翻译是非成员函数重载,其中有几个是在之前文章中有实现过的,所以应该比较好理解
在这里插入图片描述
当我们在使用某一个函数不知道要包含哪个头文件的时候,我们可以从这里看

在这里插入图片描述

Construct string (构造string)

string()空字符串构造函数(默认构造函数)

英文解释:Constructs an empty string, with a length of zero characters.
翻译:构造一个长度为零个字符的空字符串。

int main()
{
string s1;
return 0;
}

在这里插入图片描述

string (const string& str) 拷贝构造函数

英文解释:Constructs a copy of str.
翻译:拷贝构造str

int main()
{
string s2("jack john");
string s3(s2);
cout << s3 << endl;
return 0;
}

在这里插入图片描述

string (const string& str, size_t pos, size_t len = npos)

英文解释:Copies the portion of str that begins at the character position pos and spans len characters (or until the end of str, if either str is too short or if len is string::npos).
翻译:复制str中从字符位置pos开始并跨越len个字符的部分(如果str太短或len为string::npos,则复制到str的末尾)

这个函数的意思是从string中的pos位置开始取len个长度去构造出str

而npos就是上面提到的静态成员常量,他的值是-1

用图表示就像下面这样

在这里插入图片描述
当len的长度超过pos位置到结束的最大长度后,就是有多少取多少
在这里插入图片描述
而如果len的值没有传,或者传的值为npos,那么就从pos位置开始一直取到末尾结束

在这里插入图片描述
为什么len=npos就是取末尾结束呢?
其实我们注意看len的类型是size_t,而npos的值为-1,在之前的文章中有提到过size_t是无符号整数,他是没有负数的,当无符号整数len为-1时,其实表示的是len为无符号整数的最大值,既然是最大值,那应该是已经超过了从pos位置开始到结束的长度,所以就直接取到从pos位置到末尾的长度

而不传len的参数为什么也是取到末尾结束呢?
这是因为len=npos是缺省参数,len不传值的时候就默认传npos

 int main()
{
string s2("jack john");
string s4(s2, 5, 3);
string s5(s2, 5, 10);
cout << s4 << endl;
cout << s5 << endl;
return 0;
}

在这里插入图片描述

string (const char* s)复制构造

英文解释:Copies the null-terminated character sequence (C-string) pointed by s
翻译:复制s指向的以null结尾的字符序列(C字符串)
简单的来说就是string去复制构造一个字符串

int main()
{
string s6("jack");
cout << s6 << endl;
return 0;
}

在这里插入图片描述

string (const char* s, size_t n)

英文解释:Copies the first n characters from the array of characters pointed by s
翻译:从s指向的字符数组中复制前n个字符。

int main()
{
string s6("jack");
string s7(s6, 0);
string s8(s6, 1);
string s9(s6, 2);
string s10(s6, 3);
string s11(s6, 4);
cout << "s7 " << s7 << endl;
cout << "s8 " << s8 << endl;
cout << "s9 " << s9 << endl;
cout << "s10 " << s10 << endl;
cout << "s11 " << s11 << endl;
return 0;
}

在这里插入图片描述
根据什么的结果可以得出,n为0表示从前0个开始复制,n为1表示前1个开始复制…

string (size_t n, char c)

英语解释:Fills the string with n consecutive copies of character c
翻译:用字符c的n个连续副本填充字符串

int main()
{
string s12(10, 'x');
cout << s12 << endl;
return 0;
}

在这里插入图片描述

补充

上面代码中可以直接用<<是因为这个功能已经实现了运算符重载
在这里插入图片描述
我们甚至还可以这样写
在这里插入图片描述

遍历string

方式一size与operator[ ]

因为string是一个类,我们并不能拿到这个字符数组的指针…(私有限制了我们不能去访问),所以要想获取这个字符串的长度,就可以用size,这个size是已经实现了的,我们可以直接用,他的功能就是得到这个字符串中字符的长度

在这里插入图片描述
此外还有运算符重载operator[ ]我们也可以直接用,这个operator[]是让我们可以像数组一样去用s1

在这里插入图片描述

int main()
{
string s1("jack john");
for (int i = 0; i < s1.size(); i++)
{
cout << s1[i] << " ";
}
cout << endl;
for (int i = 0; i < s1.size(); i++)
{
s1[i]++;
cout << (s1[i]) << " ";
}
return 0;
}

在这里插入图片描述

由上面的结果可以看出通过s1[i]++我们可以修改s1的字符,并且遍历s1,我们也可以加const去修饰,让s1不可以被修改
在这里插入图片描述

方式二迭代器iterator

先看看下面模拟实现的string

class string
{
public:
char& operator[](size_t pos)
{
return _str[pos];
}
private:
char* _str;
size_t _size;
size_t _capacity;
};

在这里插入图片描述
str是字符串中的首元素位置,c++为了和c语言兼容所以在这个字符串中会有\0,size是计算这个的长度,但是\0是不会被计算到size里的,所以size的大小为8
在这里插入图片描述
知道了这些现在来讲解一下具体是如何遍历的
我们需要用到string中的iterator,iterator是一个迭代器,这个迭代器是定义在string的类域里面的,所以在用的时候我们要用域作用限定符
在这里插入图片描述

int main()
{
string s1("jackjohn");
string::iterator it1 = s1.begin();
while (it1 != s1.end())
{
cout << *it1 << " ";
++it1;
}
return 0;
}

在这里插入图片描述
迭代器用起来像指针一样(不是指针),begin像首元素的地址,end就是\0的地址,当begin=end的时候就结束了

又因为string中有\0,但是\0不是有效字符,所以end表示为最后一个有效字符的下一个位置,而begin表示为第一个有效字符,因此从这句话我们可以推断出字符的有效范围是[begin,end)
这里也顺便提一下,之前文章C++入门基础(四)中的auto也解释过,auto在复杂情况下要少用
在这里插入图片描述
上面的iterator为正向迭代器,有正向当然也有反向

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

在这里插入图片描述

此外iterator是可以修改字符的

int main()
{
string s1("jackjohn");
string::iterator it1 = s1.begin();
while (it1 != s1.end())
{
cout << *it1 << " ";
++it1;
}
cout << endl;
it1 = s1.begin();
while (it1 != s1.end())
{
*it1=*it1+2;
cout << *it1 << " ";
++it1;
}
return 0;
}

在这里插入图片描述

方式三范围for(底层就是迭代器)

范围for是可以遍历容器的,因为范围for的底层就是迭代器

int main()
{
string s1("jackjohn");
for (auto e : s1)
{
cout << e;
}
cout << endl;
return 0;
}

在这里插入图片描述


原文地址:https://blog.csdn.net/2301_79178723/article/details/140278237

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!