C++——string之迭代器

迭代器iterator

(一)迭代器概念

    迭代器就是一种访问string中的各个元素的机制,类似于指针(其底层实现就是指针,同样有解引用、++、- -的操作);

(二)迭代器种类

    迭代器总共有四种:正向迭代器(iterator)、反向迭代器(reverse_iterator)、只读迭代器(const_iterator)、只读反向迭代器(const_reverse_iterator);
    当我们有针对const修饰的对象时,则必须使用只读迭代器const_iterator

(三)接口

  1、begin()、rbegin()、cbegin()、crbegin()

		begin():指向容器第一个元素的位置(可读可写)
		rbegin():指向容器最后一个元素的位置(可读可写)
		cbegin():指向容器第一个元素的位置(只读)
		crbegin():指向容器最后一个元素的位置(只读)

  2、end()、rend()、cend()、crend()

		end():指向容器最后一个元素的下一个位置(可读可写)
		rend():指向容器第一个元素的前一个位置(可读可写)
		cend():指向容器最后一个元素的下一个位置(只读)
		crend():指向容器第一个元素的前一个位置(只读)

(四)遍历string对象的三种方式

string str("123456");

  1、for循环遍历

for(int i = 0; i < str.size(); i++){
	cout << str[i] << " ";
}

  2、迭代器遍历

string::iterator it = str.begin();
while (it != str.end()){
	cout << *it << " ";
	it++;
}

  3、范围for遍历(内部实现也是使用迭代器)

for(const auto& ch : str){
	cout << ch << " ";
}

(五)迭代器失效

  1、增容时失效

void test(){
	string str("123456");
	string::iterator it = str.begin();

	str.reserve(100);
}

    此时经过增容之后,增容的函数内部会实现原有空间的释放的过程,就会导致此时迭代器的指向不再是指向现在的对象,这就导致了迭代器失效,此时必须要重新定义迭代器使其指向现在的对象空间;
    同理,调用insert()push_back()append()resize() 等等这些涉及到增容的函数时同样可能会这种问题;

  2、缩容时失效

void test(){
	string str("123456");
	string::iterator it = str.rbegin();

	resize(3);
}

    上面这段代码中,迭代器先指向最后一个元素,当缩容时,迭代器指向的并不再是有效字符的位置,此时迭代器也失效了;

  3、删除时失效

void test(){
	string str("123456");
	string::iterator it = str.begin();
	
	str.erase(0, 1);
}

    这段代码中,迭代器一开始指向是字符串的首元素,然后调用erase() 接口将首元素删除,此时原本第二个元素到了首元素的位置,这种情况下,迭代器也会失效;

  P.S. 总结来说,当我们使用迭代器,同时又要对对象内容或者容量进行修改时,再修改结束后一定要更新迭代器以确保迭代器不会失效。

### C++ `string` 类型迭代器的使用 在C++中,`std::string` 支持多种类型的迭代器用于访问和操作字符串中的字符。这些迭代器允许程序员以更灵活的方式遍历和修改字符串的内容。 #### 基本概念 迭代器是一种泛化指针,可以用来指向容器(如数组、列表或字符串)中的元素。对于`std::string`而言,提供了正向迭代器来顺序访问其内部存储的数据[^2]。 #### 创建与初始化 可以通过成员函数`begin()` 和 `end()` 来获取指向字符串起始位置以及结束位置之后的一个迭代器对象: ```cpp #include <iostream> #include <string> using namespace std; int main(){ string str = "hello"; // 获取迭代器 auto iter_begin = str.begin(); auto iter_end = str.end(); while(iter_begin != iter_end){ cout << *iter_begin; ++iter_begin; } } ``` 这段代码展示了如何创建并使用基本的前向迭代器来逐个打印出字符串中的每一个字符[^1]。 #### 范围for循环的应用 除了显式的声明迭代器外,在现代C++版本里还可以利用范围for语句简化语法: ```cpp #include <iostream> #include <string> using namespace std; int main(){ string s1("Test String"); for(char ch : s1){ cout << ch ; } cout << endl; } ``` 这里展示了一个简单的例子,其中定义了一个名为`s1` 的字符串变量,并通过增强版for循环实现了对其所有字符的一次性输出。 #### 修改元素值 如果想要改变某个特定索引处的字符,则可以直接解引用相应的迭代器来进行赋值操作;需要注意的是只有当该迭代器不是常量时才可执行写入动作: ```cpp #include <iostream> #include <string> using namespace std; int main(){ string str = "world"; // 非const迭代器可用于更改所指向的对象 for(auto& c : str){ if(c >= 'a' && c <= 'z'){ c -= ('a'-'A'); // 将小写字母转换成大写形式 } } cout<<str<<"\n"; } ``` 此片段说明了怎样借助于非恒定性的引用参数实现对原始序列内各成分属性变更的效果[^3]。 #### 插入新项 虽然标准库并不支持直接经由迭代器往现有区间之间插入新的项目,但是能够运用其他辅助工具达成相似目的——比如采用算法库里的insert方法或者构造临时vector再拼接回去等方式间接完成任务[^4]。 #### 删除指定位置上的单个节点/连续子串 同样地,删除操作也不宜单纯依赖迭代器本身去实施,而是应该考虑调用erase接口配合定位到待移除部分前后边界的位置信息从而达到预期效果。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值