目录
C++中如何操作字符串?
什么是string?
使用string
常用构造函数
长度和容量相关的函数
访问string类对象中的字符
方式一:用下标的方式
方式二:用迭代器(string的迭代器底层是指针)
方式三:范围for(C++11)
vs2022下的string结构和范围for原理
对string对象的修改操作函数
非成员函数
在C中常用字符数组表示字符串,使用#include
标准库类型string表示可变长的字符序列,本质上string是类模板basic_string实例化,用于存放char类型:
使用string须包含其头文件,string定义在命名空间std中,使用时可以如此:
#include
using std::string;
使用示例:(注:string重载了<<操作符,可以用其输出字符串内容)
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
using std::string;
using std::cout;
using std::endl;
int main()
{
string s1;//默认构造的是空串
string s2("hello string");
string s3(s2);
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
return 0;
}
输出:
函数原型 函数名:函数作用
size_t size() const; size/length :返回字符串的长度
void resize(size_t n,char c) resize:修改字符串的长度为n,变长就用c填充
size_t capacity() const; capacity:返回已分配的空间的容量
void reserve (size_t n = 0); reserve:为字符串预留空间(可用于减少频繁扩容)
void clear(); clear:清空字符(改变长度=0,不改变容量)
bool empty() const; empty:字符串是空串则返回true,否则返回false
使用示例:
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
using std::string;
using std::cout;
using std::endl;
int main()
{
string s("hello string");
cout << s << endl;
//size
cout << s.size() << endl;
//resize
s.resize(5);
cout << s << endl;
s.resize(10, 'x');
cout << s << endl;
//capacity,reserve
cout << s.capacity() << endl;
s.reserve(20);
cout << s.capacity() << endl;
//clear
s.clear();
cout << s << endl;
//empty
if (s.empty())
cout << "s is empty" << endl;
return 0;
}
输出:(注意:因为底层实现string时考虑了内存对齐等,故开辟的空间可能不是reserve准确的空间)
因为string支持了[]的运算符重载,也可用at成员函数访问字符,区别是后者在越界时会抛异常。
函数原型:(每个函数提供了其const版本,用于支持const对象) char& operator[] (size_t pos); const char& operator[] (size_t pos) const; char& at (size_t pos); const char& at (size_t pos) const;
可将迭代器当成字符指针理解,begin返回的是首字符的迭代器,end返回的是最后一个字符的后一个位置的迭代器。
函数原型: iterator begin(); const_iterator begin() const;iterator end(); const_iterator end() const;
范围for的底层是转化为迭代器去访问元素的。
使用示例:
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
using std::string;
using std::cout;
using std::endl;
int main()
{
string s("welcome to string");
//一:下标访问
for (int i = 0; i < s.size(); i++)
cout << s[i];
cout << endl;
//二:迭代器访问
string::iterator it = s.begin();//取string类域中的iterator
while (it != s.end())
cout << *it++ << " ";
cout << endl;
//三:范围for
for (auto &e : s)//用引用可以修改字符串中的元素
cout << ++e ;
cout << endl;
return 0;
}
输出:
vs下string的结构较为复杂:
用联合体存储字符数组或字符指针:
当字符串长度较小时,使用内部固定的字符数组_Buf[]来存放字符串当字符串长度较大时时,从堆上开辟空间,用_Ptr指针指向字符串首字符
监视窗口中可见:用_Mysize存储长度size,用_Myres存储容量capacity
了解了其结构后,再去观察范围for的反汇编代码,是否底层是迭代器呢?
可见调用了两个函数,_Unchecked_begin()和_Unchecked_end(),猜测和begin()、end()相似。
查看其函数定义,结合上面结构体的定义可知,_Unchecked_begin()返回的是字符串首字符的指针,可见范围for的本质是指针(也就是迭代器)。
可见当存储长度较小字符串时返回_Buf,反之返回_Ptr
高频使用函数:
void push_back (char c); 尾插一个字符c
append/operator += 函数:在字符串后追加字符串
const char* c_str() const; 返回c格式的字符串
注:string类中定义了变量npos表示size_t类型的最大值
size_t find (const string& str, size_t pos = 0) const;从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置,没找到则返回npos
size_t rfind (const string& str, size_t pos = npos) const;从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置,没找到则返回npos
string substr (size_t pos = 0, size_t len = npos) const;在str中从pos位置开始,截取len个字符构造string对象,然后返回
使用示例:
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
using std::string;
using std::cout;
using std::endl;
int main()
{
string s1("hello string");
string s2("hello world");
//push_back
s1.push_back('x');
s1.push_back('y');
s1.push_back('z');
cout << s1 << endl << endl;
//append
s1.append(s2);
cout << s1 << endl;
s1.append("!!!");
cout << s1 << endl << endl;
//+=
s1 += s2;
cout << s1 << endl;
s1 += "!!!";
cout << s1 << endl << endl;
//c_str
printf("%s\n", s1.c_str());
printf("%s\n\n",s2.c_str());
//find
int pos = s1.find('x');
if (pos != string::npos)
cout << s1[pos] << endl<
输出:
非成员函数
operator+传值返回两个string对象合并后的string对象,效率较低
relationnal operators是重载了==,<,>等比较运算符,比较的是字符的ASCII码,与strcmp类似来比较两个字符串大小。
void swap (string& x, string& y);交换函数,重载了std的swap函数,效率更高,因为底层实现是交换两个string对象内部的字符指针。
operator>>运算符重载,输入字符串到string对象中,遇到空格或换行就停止。
operator<<运算符重载,输出string对象中字符串的内容。
istream& getline (istream& is, string& str);输入字符串到string对象中,遇到空格不停止,遇到换行才停止。
你可能感兴趣的:(C++,c++,学习,开发语言)