前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C++修行之道】string类的使用

【C++修行之道】string类的使用

作者头像
走在努力路上的自己
发布2024-07-13 08:40:53
520
发布2024-07-13 08:40:53
举报

一.C语言中的字符串

C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数, 但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可 能还会越界访问。

二、标准库中的string类 (了解)

2.1 string类(了解)

1. 字符串是表示字符序列的类

2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。

3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string)。

4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,用char_traits 和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。

5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。

C++中对于string的定义是:typedef basic_string string;

  • 使用 typedef 关键字将 basic_string 类定义为一个新的类型 string
  • 这意味着,以后在代码中提到 string 时,其实是在引用 basic_string 类。

也就是说C++中的string类是一个泛型类,由模板而实例化的一个标准类,本质上不是一个标准数据类型。

至于为什么不直接用String标准数据类型而用类是因为编码

每个国家的语言不同 比如说英语使用26个英文字母基本就能表述所有的单词 但是对于中文的字符呢?就要用其他编码方式啊(比如说utf-8)

总结:

  1. string是表示字符串的字符串类
  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
  3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
  4. 不能操作多字节或者变长字符的序列。
  5. 在使用string类时,必须包含#include头文件以及using namespace std

2.2 帮助文档阅读

(1) empty string constructor (default constructor)

Constructs an empty string, with a length of zero characters.

(2) copy constructor

Constructs a copy of str.

(3) substring constructor

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).

(4) from c-string

Copies the null-terminated character sequence (C-string) pointed by s.

(5) from buffer

Copies the first n characters from the array of characters pointed by s.

(6) fill constructor

Fills the string with n consecutive copies of character c.

(7) range constructor

Copies the sequence of characters in the range [first,last), in the same order.

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

构造一个空字符串,长度为零个字符。

(2) 拷贝构造函数

构造一个 str 的副本。

(3) 子字符串构造函数

复制 str 从字符位置 pos 开始并跨越 len 个字符的部分

(如果 str 太短或 len 是 string::npos,则复制到 str 的末尾)。

(4) 从 C 风格字符串构造

复制由 s 指向的以 null 结尾的字符序列(C 字符串)。

(5) 从字符串序列构造

复制由 s 指向的字符数组中的前 n 个字符。

(6) 填充构造函数

用 n 个字符 c 的连续副本填充字符串。

(7) 范围构造函数

复制范围 [first,last) 中的字符序列,顺序保持不变。

三、 string类的常用接口说明

3.1 string类对象的常见构造

构造函数

函数名称

功能说明

string()

空字符串构造函数(重点)

构造空的 string 类对象,即空字符串

string(const char* s)

从 C-string 构造(重点)

用 C-string 来构造 string 类对象

string(size_t n, char c)

填充构造函数

string 类对象中包含 n 个字符 c

string(const string& s)

拷贝构造函数(重点)

用一个已有的 string 对象 s 构造新的 string 对象

代码语言:javascript
复制
void test01()
{
	// 常用
	string s1;
	string s2("hello world");
	string s3(s2);
	
	// 不常用, 了解
	string s4(s2, 3, 5);
	string s5(s2, 3);
	string s6(s2, 3, 30);
	string s7("hello world", 5);
	string s8(10, 'x');
	
	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
	cout << s5 << endl;
	cout << s6 << endl;
	cout << s7 << endl;
	cout << s8 << endl;
	
	cin >> s1;
	cout << s1 << endl;
}

3.2 string类对象的容量操作

函数名称

功能说明

size(重点)

返回字符串有效字符长度

length

返回字符串有效字符长度

capacity

返回空间总大小

empty(重点)

检测字符串是否为空串,若为空返回 true,否则返回 false

clear(重点)

清空有效字符

reserve(重点)

为字符串预留空间

resize(重点)

将有效字符的个数改为 n 个,多出的空间用指定字符填充

注意:

1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一

致,一般情况下基本都是用size()。

2. clear()只是将string中有效字符清空,不改变底层空间大小。

3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字 符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的 元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。

4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于 string的底层空间总大小时,reserver不会改变容量大小。

3.3 string类对象的访问及遍历操作

函数名称

功能说明

operator[](重点)

返回 pos 位置的字符,用于 const string 类对象的调用

begin 和 end

begin 获取一个字符的迭代器,end 获取最后一个字符下一个位置的迭代器

rbegin 和 rend

rbegin 获取一个反向迭代器指向最后一个字符,rend 获取一个反向迭代器指向第一个字符前一个位置

范围 for

C++11 支持更简洁的范围 for 新遍历方式

字符串类的简单实现
代码语言:javascript
复制
class String
{
public:
	// 引用返回
	// 1.减少拷贝
	// 2.修改返回对象
	char& operator[](size_t i)
	{
		assert(i < _size)
		return _str[i];
	}
private:
	char* _str;
	size_t _size;
	size_t _capacity;
};

其中operator[]操作符重载允许通过下标访问和修改字符串中的字符。通过返回字符的引用,可以避免不必要的拷贝并直接修改字符串内容,同时通过assert保证了安全性。

代码语言:javascript
复制
void test02()
{
	string s1("hello world");
	cout << s1.size() << endl;// 不计算'\0'
	// cout << s1.length() << endl;

	// 访问每个字符并令其++
	for (size_t i = 0; i < s1.size(); i++)
	{
		s1[i]++;
	}
	cout << endl;
	s1[0] = 'x';

	// 越界会被检查
	// s1[20];

	// 访问每个字符
	for (size_t i = 0; i < s1.size(); i++)
	{
		cout << s1.operator[](i) << " ";
		cout << s1[i] << " ";
	}
	cout << endl;

	const string s2("hello world");
	// const 不能修改
	// s2[0] = 'x';
}

通过重载的 operator[] 访问和修改字符串中的字符,同时也演示了对常量字符串对象进行修改时的限制。代码还包含了越界访问检查,通过 assert 保证安全性。

3.4 string类对象的修改操作

函数名称

功能说明

push_back

在字符串末尾插入字符 c

append

在字符串末尾追加一个字符串

operator+=

在字符串末尾追加字符串 str(重点)

c_str

返回 C 格式字符串(重点),用于与其他 C/C++ 函数交互,返回的字符串是临时的,不应被修改

find + npos

从字符串 pos 位置开始往后找字符 c,返回该字符在字符串中的位置,找不到时返回 string::npos(重点)

rfind

从字符串 pos 位置开始往前找字符 c,返回该字符在字符串中的位置(注意:rfind 通常用于查找子字符串,而非单个字符 c 的向前查找,对于单个字符,直接使用 find 从末尾开始查找即可)

substr

在字符串中从 pos 位置开始,截取 n 个字符,然后将其返回

注意:

1. 在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。

2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

代码语言:javascript
复制
void test03()
{
	// 构造
	string s1("hello world");

	// 隐式类型转换
	string s2 = "hello world";

	const string& s3 = "hello world";
	// 引用的临时对象, 临时对象具有常性

	string s4("hello world");
	push_back(s4);
	push_back("hello world");
}

3.5 string类非成员函数

函数/运算符

功能说明

operator+

字符串连接运算符,但尽量少用,因为传值返回导致深拷贝,效率低

operator>> (重点)

输入运算符重载,用于从输入流中提取字符串到字符串对象中

operator<< (重点)

输出运算符重载,用于将字符串对象的内容发送到输出流中

getline (重点)

从输入流中获取一行字符串,直到遇到换行符('\n'),不包括换行符

relational operators (重点)

大小比较运算符重载,包括 <、<=、>、>=、==、!=,用于比较两个字符串对象的大小

上面的几个接口大家了解一下,下面的OJ题目中会有一些体现他们的使用。string类中还有一些其他的 操作,这里不一一列举,大家在需要用到时不明白了查文档即可。

3.6 vs和g++下string结构的说明

注意:下述结构是在32位平台下进行验证,32位平台下指针占4个字节。

vs下string的结构

string总共占28个字节,内部结构稍微复杂一点,先是有一个联合体,联合体用来定义string中字

符串的存储空间

  • 当字符串长度小于16时,使用内部固定的字符数组来存放
  • 当字符串长度大于等于16时,从堆上开辟空间
代码语言:javascript
复制
union _Bxty
{ 
  // storage for small buffer or pointer to larger one
  value_type _Buf[_BUF_SIZE];
  pointer _Ptr;
  char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;

这种设计也是有一定道理的,大多数情况下字符串的长度都小于16,那string对象创建好之后,内

部已经有了16个字符数组的固定空间,不需要通过堆创建,效率高。

其次:还有一个size_t字段保存字符串长度,一个size_t字段保存从堆上开辟空间总的容量

最后:还有一个指针做一些其他事情。

故总共占16+4+4+4=28个字节。

g++下string的结构

G++下,string是通过写时拷贝实现的,string对象总共占4个字节,内部只包含了一个指针,该指

针将来指向一块堆空间,内部包含了如下字段:

  • 空间总大小
  • 字符串有效长度
  • 引用计数
代码语言:javascript
复制
struct _Rep_base
{
 size_type _M_length;
 size_type _M_capacity;
 _Atomic_word _M_refcount;
};
  • 指向堆空间的指针,用来存储字符串。

四、string操作的代码示例

4.1 三种遍历方式

代码语言:javascript
复制
void test04()
{
	string s1("hello world");

	// 遍历方式1: 下标 + []
	for (size_t i = 0; i < s1.size(); i++)
	{
		cout << s1[i] << " ";
	}
	cout << endl;

	// 遍历方式2: 迭代器
	string::iterator it1 = s1.begin();
	while (it1 != s1.end())
	{
		*it1 += 3;
		cout << *it1 << " ";
		++it1;
	}
	cout << endl;

	// 遍历方式3: 范围for
	// 底层实现方式都是迭代器实现
	for (auto e : s1)
	{
		e++;
		cout << e << " ";
	}
	cout << endl;

	//cout << typeid(it1).name() << endl;

	/*list<int> lt1;
	lt1.push_back(1);
	lt1.push_back(2);
	lt1.push_back(3);

	list<int>::iterator it = lt1.begin();
	while (it != lt1.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;*/
}


//template<class T>
//struct ListNode
//{
//	ListNode <T>* _next;
//	ListNode <T>* _prev;
//	T _data;
//};
//
//template<class T>
//class list
//{
//private:
//	ListNode<T>* _head;
//};
代码语言:javascript
复制
    // 遍历方式1: 下标 + []
	for (size_t i = 0; i < s1.size(); i++)
	{
		cout << s1[i] << " ";
	}
	cout << endl;
  • 使用下标操作符 [] 遍历字符串 s1 并输出每个字符。s1.size() 返回字符串的长度。
代码语言:javascript
复制
	// 遍历方式2: 迭代器
	string::iterator it1 = s1.begin();
	while (it1 != s1.end())
	{
		*it1 += 3;
		cout << *it1 << " ";
		++it1;
	}
  • 使用 string::iterator 迭代器遍历字符串 s1
  • *it1 += 3; 将迭代器指向的每个字符的 ASCII 码值增加 3 并输出。
代码语言:javascript
复制
	// 遍历方式3: 范围for
	// 底层实现方式都是迭代器实现
	for (auto e : s1)
	{
		e++;
		cout << e << " ";
	}
	cout << endl;
  • 使用范围 for 遍历字符串 s1
  • e++ 增加每个字符的 ASCII 码值并输出。需要注意的是,这里 e 是字符的一个拷贝,修改它并不会影响原字符串。

4.2 迭代器的规则

代码语言:javascript
复制
void test05()
{
	const string s1("hello world");
	//string::const_iterator it1 = s1.begin();
	auto it1 = s1.begin();
	while (it1 != s1.end())
	{
		// 指向的内容不能修改
		// *it1 += 3;

		cout << *it1 << " ";
		++it1;
		// const_iterator 本身可以++
	}
	cout << endl;
	/*string::iterator it1 = s1.begin();
	while (it1 != s1.end())
	{
		*it1 += 3;
		cout << *it1 << " ";
		++it1;
	}
	cout << endl;*/
}

4.3 反向迭代器的使用

代码语言:javascript
复制
void test06()
{
	const string s1("hello world");
	//string::const_iterator it1 = s1.begin();
	auto it1 = s1.begin();
	while (it1 != s1.end())
	{
		// 不能修改
		//*it1 += 3;

		cout << *it1 << " ";
		++it1;
	}
	cout << endl;

	//string::const_reverse_iterator cit1 = s1.rbegin();
	auto cit1 = s1.rbegin();
	while (cit1 != s1.rend())
	{
		// 不能修改
		//*cit1 += 3;

		cout << *cit1 << " ";
		++cit1;
	}
	cout << endl;

	string s2("hello world");
	string::reverse_iterator it2 = s2.rbegin();
	//auto it2 = s2.rbegin();
	while (it2 != s2.rend())
	{
		//*it2 += 3;

		cout << *it2 << " ";
		++it2;
	}
	cout << endl;
}
代码语言:javascript
复制
	while (it1 != s1.end())
	{
		// 不能修改
		//*it1 += 3;

		cout << *it1 << " ";
		++it1;
	}
  • while 循环中,it1 从字符串的开头遍历到结尾 (s1.end()),并输出每个字符。由于 it1const_iterator,所以不能通过它修改字符串的内容
代码语言:javascript
复制
while (cit1 != s1.rend())
	{
		// 不能修改
		//*cit1 += 3;

		cout << *cit1 << " ";
		++cit1;
	}
  • const_reverse_iterator,用于从字符串的末尾向开头遍历。
  • while 循环中,cit1 从字符串的末尾 (s1.rbegin()) 遍历到开头 (s1.rend()),并输出每个字符。由于 cit1const_reverse_iterator,所以不能通过它修改字符串的内容。
代码语言:javascript
复制
	while (it2 != s2.rend())
	{
		//*it2 += 3;

		cout << *it2 << " ";
		++it2;
	}
  • while 循环中,it2 从字符串的末尾 (s2.rbegin()) 遍历到开头 (s2.rend()),并输出每个字符。虽然 it2 是反向迭代器,可以修改字符串的内容,但注释掉的 *it2 += 3 行展示了这一点。

4.4 排序

代码语言:javascript
复制
void test07()
{
	string s1("hello world");
	cout << s1 << endl;
	// s1按字典序排序

	// 排序一部分
	sort(s1.begin(), s1.end());

	// 第一个和最后一个参与排序
	sort(++s1.begin(), --s1.end());

	// 前五个排序  [0, 5)
	// sort(s1.begin(), s1.begin() + 5);

	cout << s1 << endl;
}

4.5 尾插的方式

代码语言:javascript
复制
void test08()
{
	string s1("hello world");
	cout << s1 << endl;

	s1.push_back('x');
	cout << s1 << endl;

	s1.append(" yyyy!!");
	cout << s1 << endl;

	s1 += 'y';
	s1 += "zzzzz";
	cout << s1 << endl;
}

4.6 替换和头插

代码语言:javascript
复制
void test09()
{
	string s1("hello world");
	cout << s1 << endl;

	s1.assign("111111");
	cout << s1 << endl;
	
	// 慎用, 因为效率不高 -> O(N)
	// 实践中需求也不高
	string s2("hello world");
	s2.insert(0, "xxxx");
	cout << s2 << endl;
	
	char ch = 'z';
	s2.insert(0, 1, ch);
	s2.insert(0, 1, 'y');
	cout << s2 << endl;

	// 没有这个版本的头插
	// s2.insert(0, 'y');
	// cout << s2 << endl;

	s2.insert(s2.begin(), 'y');
	cout << s2 << endl;

	s2.insert(s2.begin(), s1.begin(), s1.end());
	cout << s2 << endl;
}
  • s1.assign("111111"); 使用 assign 方法将 s1 的内容替换为 "111111"
  • s2.insert(0, "xxxx");s2 的开头插入字符串 "xxxx"
  • s2.insert(0, 1, ch);s2 的开头插入字符 'z'
  • s2.insert(0, 1, 'y');s2 的开头插入字符 'y'
  • s2.insert(s2.begin(), 'y');s2 的开头插入字符 'y',使用的是迭代器。
  • s2.insert(s2.begin(), s1.begin(), s1.end());s2 的开头插入字符串 s1 的所有内容。

4.7 删除和修改

代码语言:javascript
复制
void test10()
{
	string s1("hello world");
	cout << s1 << endl;

	// 效率不高, 慎用, 和inset类似
	s1.erase(0,1);// 头删
	cout << s1 << endl;

	// s1.erase(5);
	s1.erase(5,100);
	cout << s1 << endl;

	string s2("hello world");
	s2.replace(5, 1, "%20");
	// 字符串的替换
	cout << s2 << endl;

	// 不建议这样使用,因为要挪动数据
	string s3("hello world hello char");
	for (size_t i = 0; i < s3.size();)
	{
		if (s3[i] == ' ')
		{
			s3.replace(i, 1, "%20");
			i += 3;
		}
		else 
		{
			i++;
		}
	}
	cout << s3 << endl;

	string s4("hello world hello double");
	string s5;
	for (auto ch : s4)
	{
		if (ch != ' ')
		{
			s5 += ch;
		}
		else {
			s5 += "%20";
		}
	}
	cout << s5 << endl;
}
代码语言:javascript
复制
	// 不建议这样使用,因为要挪动数据
	string s3("hello world hello char");
	for (size_t i = 0; i < s3.size();)
	{
		if (s3[i] == ' ')
		{
			s3.replace(i, 1, "%20");
			i += 3;
		}
		else 
		{
			i++;
		}
	}
  • 循环遍历字符串 s3,将所有空格字符 ' ' 替换为 "%20"。由于每次替换一个字符为三个字符,循环变量 i 在替换后需要增加 3,否则只增加 1
  • 直接修改字符串
代码语言:javascript
复制
    string s4("hello world hello double");
	string s5;
	for (auto ch : s4)
	{
		if (ch != ' ')
		{
			s5 += ch;
		}
		else {
			s5 += "%20";
		}
	}
	cout << s5 << endl;
  • 使用范围 for 循环遍历字符串 s4,将所有非空格字符添加到 s5,将空格字符替换为 "%20" 添加到 s5
  • 构造新的字符串

4.8 string的扩容

代码语言:javascript
复制
void TestPushBack()
{
	string s;
	// 知道需要多少空间, 提前开好
	s.reserve(200);
	// 仅仅影响容量capacity() ,不影响数据个数size()
	// s[100] = 'x';
    // 无法访问

	size_t sz = s.capacity();
	cout << "capacity changed: " << sz << '\n';
	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';
		}
	}
}

字符串的增长策略是C++标准库实现的一种优化手段。不同的实现可能采用不同的策略,常见的策略包括按倍数增长(如1.5倍)。这种策略能够有效减少内存分配次数,提高性能,同时在内存使用和性能之间取得平衡。

代码语言:javascript
复制
void test11()
{
	//string s1("hello world hello bit");
	string s1;
	//cout << s1.size() << endl;
	//cout << s1.capacity() << endl;
	//cout << s1.max_size() << endl;
	//for (size_t i = 0; i < s1.max_size(); i++)
	//{
	//	s1 += 'x';
	//}

	//cout << s1.size() << endl;

	TestPushBack();

	string s1("111111111");
	//string s2("11111111111111111111111111111111111111111111111111");

	cout << s1.capacity() << endl;

	 reserve 保留
	 reverse 逆置 反转
	//s1.reserve(100);
	//cout << s1.capacity() << endl;

	//s1.reserve(20);
	//cout << s1.capacity() << endl;
}

int main()
{
	test11();
}
  • 调用 s1.reserve(20),将 s1 的容量至少增加到 20。
  • 然而,由于之前已经将容量增加到 100,reserve 不会缩小容量,所以输出仍然是 100 或更大。
  • 调用 s1.reserve(10),将 s1 的容量至少增加到 10。
  • 然而,由于之前容量 < 16,reserve 会缩小容量,所以输出是 15。
注:缩容的本质是时间换空间

4.9 调整字符串

代码语言:javascript
复制
void test12()
{
	string s1;
	//s1.resize(5, '0');
	s1.resize(5);
	s1[4] = '3';
	s1[3] = '4';
	s1[2] = '5';
	s1[1] = '6';
	s1[0] = '7';
	// 76543

	// 插入(空间不够会扩容)
	string s2("hello world");
	s2.resize(20, 'x');

	// 删除
	s2.resize(5);

	try
	{
		//s2[10];
		// 直接报错
		//s2.at(10);
		// 可以捕获
	}
	catch (const exception& e)
	{
		cout << e.what() << endl;
	}

	string file("test.cpp");
	FILE* fout = fopen(file.c_str(), "r");
	// file.c_str() 将 std::string 转换为 C 风格的字符串
	// (即 const char*),以供 fopen 使用。
	char ch = fgetc(fout);
	// 使用 fgetc 函数从文件中读取一个字符,并将其存储在 ch 中。
	while (ch != EOF)
	{
		cout << ch;
		ch = fgetc(fout);
	}
}
代码语言:javascript
复制
FILE* fout = fopen(file.c_str(), "r");
  • 使用 fopen 函数打开文件。fopen 的第一个参数是文件名,第二个参数是模式。
    • file.c_str()std::string 转换为 C 风格的字符串(即 const char*),以供 fopen 使用。
    • "r" 模式表示以只读模式打开文件。
  • fopen 返回一个指向 FILE 对象的指针 fout,用于标识打开的文件。
代码语言:javascript
复制
char ch = fgetc(fout);
  • 使用 fgetc 函数从文件中读取一个字符,并将其存储在 ch 中。
  • fgetc 每次调用时从文件中读取一个字符,并将文件指针移动到下一个字符位置。如果到达文件末尾,则返回 EOF
代码语言:javascript
复制
while (ch != EOF)
{
    cout << ch;
    ch = fgetc(fout);
}

使用 while 循环读取文件中的字符,直到遇到 EOF(文件末尾)。

  • ch != EOF 检查读取的字符是否是 EOF,如果不是,则继续循环。
  • cout << ch; 将读取的字符输出到控制台。
  • ch = fgetc(fout); 读取下一个字符并更新 ch 的值。

今天就先到这了!!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-07-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.C语言中的字符串
  • 二、标准库中的string类 (了解)
    • 2.1 string类(了解)
      • 2.2 帮助文档阅读
      • 三、 string类的常用接口说明
        • 3.1 string类对象的常见构造
          • 3.2 string类对象的容量操作
            • 3.3 string类对象的访问及遍历操作
              • 字符串类的简单实现
            • 3.4 string类对象的修改操作
              • 3.5 string类非成员函数
                • 3.6 vs和g++下string结构的说明
                • 四、string操作的代码示例
                  • 4.1 三种遍历方式
                    • 4.2 迭代器的规则
                      • 4.3 反向迭代器的使用
                        • 4.4 排序
                          • 4.5 尾插的方式
                            • 4.6 替换和头插
                              • 4.7 删除和修改
                                • 4.8 string的扩容
                                  • 注:缩容的本质是时间换空间
                                • 4.9 调整字符串
                                相关产品与服务
                                容器服务
                                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                                领券
                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档