目录
本文将对string常用函数进行说明
string基础介绍
string类的常用接口说明
string() &&string(const char* s)
拷贝:string (const string& str, size_t pos, size_t len = npos)
拷贝前n个进行构造:string (const char* s, size_t n);编辑
字符串初始化:string (size_t n, char c);编辑
string类对象的容量操作:
size() && length() && capacity()
缩小其容量以适应其当前大小:shrink_to_fit()
开辟空间:
reserve()//只会改变capacity
开空间+初始化:resize()//size和capacity动可进行改变
string类对象的修改操作
尾插:
插入一个字符push_back()
插入字符串:append()
operator+=
任意位置插入/头插
编辑
删除:erase编辑
替换:replace /查找:find
find_first_of//正着找
find_last_of//倒着找
交换swap编辑
返回C格式字符串:c_str
string类对象的访问及遍历操作
begin()&&end()//迭代器
正向遍历
rbegin() && rend()//反向遍历(反向迭代器)
编辑
operator[ ]编辑
本文将对string常用函数进行说明
string文档:cplusplus.com/reference/string/string/?kw=string
string基础介绍
string
是一个表示文本字符串的数据类型。它是一个标准库提供的类,需要包含 <string>
头文件以及using namespace std;才能使用。
使用 string
类可以方便地处理和操作文本字符串。与使用字符数组相比,string
类提供了更多的功能和灵活性,同时也避免了手动管理内存的复杂性。
-
字符串是表示字符序列的类
-
标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作 单字节字符字符串的设计特性。
-
string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信
息,请参阅basic_string)。
-
string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits
和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。
-
注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个
类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。
string类的常用接口说明
string() &&string(const char* s)
string s1;
string s2("HelloWord");
遍历s2:
for (size_t i = 0; i < s2.size(); i++)//s2.size():字符串的长度
{
s2[i]++;
}
cout<<s2[i]<<" ";//遍历
string s3="HappyEveryDay";
隐式转换:"HappyEveryDay"
是一个字符串字面值,它的类型是 const char[]
(或者可以隐式转换为 const char*
),而 s3
的类型是 std::string
。这就涉及到一个类型转换的过程,将 const char[]
或 const char*
转换为 std::string
对象。//构造+拷贝构造->优化为->构造
拷贝:string (const string& str, size_t pos, size_t len = npos)
从pos位置拷贝到行后npos个字符
若npos超过字符串长度则拷贝到末尾截止
string s3="HappyEveryDay";
string s4(s3,5,3);
string s5(s3,5,20);
npos:
npos并不是真正意义上的-1,而是无符号整型最大值,故不给值时直接打印到字符串末尾:
拷贝前n个进行构造:string (const char* s, size_t n);
字符串初始化:string (size_t n, char c);
string类对象的容量操作:
size() && length() && capacity()
string s1("HelloWord");
cout<<s1.size()<<endl;//9
cout<<s1.length()<<endl;//9
二者差别不大,只是为了保持一致和使用方便就引入了size
capacity:空间大小
缩小其容量以适应其当前大小:shrink_to_fit()
int main()
{
std::string str = "Hello, world!";
// 在一系列操作后,字符串对象可能有多余的容量
std::cout << "Capacity before: " << str.capacity() << std::endl;
// 使用 shrink_to_fit() 函数,要求字符串对象缩小容量
str.shrink_to_fit();
std::cout << "Capacity after: " << str.capacity() << std::endl;
return 0;
}
上述代码中,我们首先创建了一个 std::string
对象 str
,并将其初始化为 "Hello, world!"
。接下来,我们输出了字符串对象的初始容量。 然后,我们使用 shrink_to_fit()
函数,对字符串对象进行了缩小容量的请求。这个函数会使字符串对象的容量与其当前大小相匹配。 最后,我们再次输出了字符串对象的容量,以展示 shrink_to_fit()
函数的效果。
请注意,shrink_to_fit()
函数的调用并不保证一定会缩小容量。具体是否发生容量的缩小取决于实现。在某些情况下,字符串对象的容量可能会保持不变。
开辟空间:
reserve()//只会改变capacity
若知道要开辟多少空间,用reserve()进行开辟,提高效率,减少扩容
以如下代码为例(不同的编译器扩容方式会有差异)
//观察扩容情况
string s;
size_t sz=s.capacity();
cout<< "making s grow:\n";
for (int i = 0; i < 100; ++i)
{
s.push_back('c');
if (sz!=s.capacity())
{
sz=s.capacity();
cout<<"capacity changed:"<<sz<<'\n';
}
}
此时的输出:
making s grow:
capacity changed:47
capacity changed:95
capacity changed:191
使用reserve():
//观察扩容情况
string s;
s.reserve(100);//提前开辟空间
size_t sz=s.capacity();
cout<< "making s grow:\n";
for (int i = 0; i < 100; ++i)
{
s.push_back('c');
if (sz!=s.capacity())
{
sz=s.capacity();
cout<<"capacity changed:"<<sz<<'\n';
}
}
输出:
making s grow:
开空间+初始化:resize()//size和capacity动可进行改变
//此时初始化的值为:‘0’
s2.resize(100,'x');//全部初始化为'x'
当然resize也可以进行删除数据:
//比size小,删除数据,保留前5个
s2.resize(5);
虽然进行了数据删除,但是空间大小并不进行缩小(capacity不变)
string类对象的修改操作
尾插:
插入一个字符push_back()
string s1("Hello");
s1.push_back(' ');
s1.push_back('!');
cout << s1 << endl;//Hello !
插入字符串:append()
operator+=
operator+=在底层意义就是进行了封装
任意位置插入/头插
string s1("Word");
s1.insert(0, "Hello");
cout << s1 << endl;
s1.insert(5, "1");
cout << s1 << endl;
s1.insert(s1.begin() + 5, ' ');
cout << s1 << endl;
输出结果:
HelloWord
Hello1Word
Hello 1Word
当然,不推荐使用,插入数据,后面数据需要后移,效率低
删除:erase
string& erase (size_t pos = 0, size_t len = npos);
从pos位置删除npos个字符
string s1("Hello Word");
s1.erase(5,1);
cout << s1 << endl; //HelloWord
不推荐使用,删除数据,后面数据需要前移,效率低
替换:replace /查找:find
string s1("Hello Word i love you");
s1.replace(pos, 1, "%20");//从pos位置后的一个字符替换为%20
size_t pos = s1.find(' '); // 找到第一个并范围下标,若没找到返回-1
pos = s1.find(' ',pos+3);//从pos+3位置向后找' '
string s1("Hello Word i love you");
size_t num = 0;
for (size_t i = 0; i < s1.size(); ++i)
{
if (s1[i] == ' ')
++num;
}
//提前开空间,减少开辟次数,提高效率,避免replace
s1.reserve(s1.size()+2*num);
size_t pos = s1.find(' '); // 找到第一个并范围下标,若没找到返回-1
while (pos != string::npos)
{
s1.replace(pos, 1, "%20"); // 从pos位置后的一个字符替换为%20
pos = s1.find(' ', pos + 3); // 从pos+3位置向后找' ',
}
cout << s1 << endl;
//以空间换时间
string s2("Hello Word i love you");
string newStr;
/*
size_t num2 = 0;
for (size_t i = 0; i < s1.size(); ++i)
{
if (s1[i] == ' ')
++num2;
}
s1.reserve(s1.size() + 2 * num2);
*/
for (size_t i = 0; i < s2.size(); ++i)
{
if (s2[i] != ' ')
newStr += s2[i];
else
newStr += "%20";
}
s2=newStr;
cout << s2 << endl;
find 还可进行寻找文件后缀等等作用
string file("string.cpp");
size_t pos = file.find('.');
if (pos != string::npos)
{
string suffix = file.substr(pos, file.size() - pos);//substr:提取从位置 poa 开始的前 file.size()-pos 个字符
cout<<suffix<<endl;//.cpp
}
find反向查找
string file("string.cpp.txt.exe");
size_t pos = file.rfind('.');
if (pos != string::npos)
{
string suffix = file.substr(pos, file.size() - pos);//substr:提取从位置 poa 开始的前 file.size()-pos 个字符
cout<<suffix<<endl;//.exe
}
find_first_of//正着找
find_first_of()
函数返回一个 size_t
类型的值,表示找到的第一个匹配字符的位置。如果没有找到任何匹配的字符,则返回 std::string::npos
。
#include <iostream>
#include <string>
int main()
{
std::string str = "Hello, world!";
std::string vowels = "aeiou";
// 查找第一个元音字母的位置
size_t pos = str.find_first_of(vowels);
if (pos != std::string::npos) {
std::cout << "The first vowel is at position " << pos << std::endl;
} else {
std::cout << "No vowels found." << std::endl;
}
return 0;
}
在示例中,std::string
类型的字符串变量 str
存储了一个字符串,vowels
表示要查找的字符集合,即元音字母。函数 find_first_of()
被用于在 str
中查找第一个匹配元音字母的字符,并返回其位置。
find_last_of//倒着找
#include <iostream>
#include <string>
int main() {
std::string str = "Hello, world!";
std::string vowels = "aeiou";
// 查找最后一个元音字母的位置
size_t pos = str.find_last_of(vowels);
if (pos != std::string::npos) {
std::cout << "The last vowel is at position " << pos << std::endl;
} else {
std::cout << "No vowels found." << std::endl;
}
return 0;
}
std::string
类型的字符串变量 str
存储了一个字符串,vowels
表示要查找的字符集合,即元音字母。函数 find_last_of()
被用于在 str
中查找最后一个匹配元音字母的字符,并返回其位置。
交换swap
注意此处的swap与库中的swap不同
string::swap是将两个指针指向进行交换,而std::swap是进行深拷贝,string::swap更加高效
// string::swap
string s1("HelloWord");
string s2("***********");
cout << s1 << endl
<< s2 << endl;
s1.swap(s2);
cout << endl
<< s1 << endl
<< s2 << endl;
// std::swap
swap(s1, s2);
cout << endl
<< s1 << endl
<< s2 << endl;
返回C格式字符串:c_str
string s1("Hello Word");
cout << (void *)s1.c_str() << endl;
s1 += '\0';
s1 += '\0';
s1 += "xxxxxxx";
cout << s1 << endl
<< s1.c_str() << endl;
c型字符串是以'\0'终止,遇到'\0'终止
而流插入/提取会忽视'\0',以s1.size();进行打印
string类对象的访问及遍历操作
begin()&&end()//迭代器
用迭代器去访问
正向遍历
string s1("Hello Word");
string::iterator it=s1.begin();//正向遍历
while (it!=s1.end())
{
cout<<*it<<" ";
++it;
}
cout<<endl;
//输出:H e l l o W o r d
//const迭代器--只读不写
string s3("Hello Word");
string::const_iterator cit=s3.begin();// const_iterator
while (cit!=s3.end())
{
cout<<*cit<<" ";
++cit;
}
cout<<endl;
另一种写法:
for(auto ch: s1) { cout<<ch<<" "; } cout<<endl;
rbegin() && rend()//反向遍历(反向迭代器)
//反向迭代
string::reverse_iterator rit =s1.rbegin();//reverse_iterato:反向迭代器
while (rit!=s1.rend())
{
cout<<*rit<<" ";
++rit;
}
cout<<endl;
//const //const_reverse_iterator
string::const_reverse_iterator crit =s1.rbegin();//auto crit=s.rbegin();
while (crit!=s1.rend())
{
cout<<*crit<<" ";
++crit;
}
cout<<endl;
输出:
operator[ ]
string也可以用下标的方式进行访问
std::string str ("Test string");
for (int i=0; i<str.length(); ++i)
{
std::cout << str[i];
}