【C++STL基础入门】string迭代器

简介: 【C++STL基础入门】string迭代器

前言


本系列STL使用VS2022+C++20版本

在C++中,标准模板库(Standard Template Library,STL)是一组强大的通用模板类和函数,它为我们提供了很多供使用的数据结构和算法。其中,string类是STL中一个非常有用的类,用于处理字符串。在使用string类时,我们经常需要遍历字符串的每个字符或者进行某些特定的操作。而实现遍历和操作的关键就是使用string迭代器。本文将详细介绍string迭代器的使用方法及其在处理字符串时的重要作用。


一、迭代器是什么?


当我们需要遍历一个集合(比如数组、列表或字符串)中的元素时,就像一个一个看每个元素,这时候迭代器就派上用场了。迭代器就像是一个指针,它可以帮助我们在集合中逐个地获取其中的元素,并且可以根据需要进行修改。你可以把迭代器想象成一个遥控器,可以让我们在集合中前进、后退,或者指向特定的元素。使用迭代器,我们不需要关心集合内部的具体实现细节,只需要专注于每个元素的访问和操作。


迭代器提供了一种抽象的方法来处理集合中的元素,它可以让我们在遍历过程中轻松访问每个元素,而不必担心底层数据结构是什么样的。迭代器分为不同的类型,每种类型有着特定的目的和功能。例如,我们可以使用迭代器来读取集合元素的值,也可以使用迭代器来修改元素的值,甚至可以删除或添加元素。


总的来说,迭代器是一种工具,帮助我们在集合中按照一定的顺序遍历和操作每个元素,使得我们能够更方便地处理集合中的数据。使用迭代器,我们可以以一种统一的方式处理不同类型的集合,提高了代码的可复用性和灵活性。


二、string迭代器


1.定义迭代器

使用string类中的静态类成员iterator

string::iterator ite;

1e1b8df94769428e9af41c792f41e12a.png

理解

当我们说到迭代器时,可以将其想象为一个类似于指针的对象,它允许我们在容器(例如字符串)中按顺序访问元素或字符。


对于字符串(std::string),我们可以使用迭代器来遍历其中的字符。迭代器可以帮助我们逐个访问字符串中的每个字符,从头到尾,或者反向从尾到头。


想象一下,你有一串字母,比如 “Hello”,可以将迭代器看作是一根指向字符的手指。开始时,指向字符串的开头,即 ‘H’。然后,你可以通过移动指针(迭代器)来访问下一个字符,指向 ‘e’,再移动指针指向 ‘l’,以此类推,直到访问到最后一个字符 ‘o’。


2.通过迭代器遍历

使用迭代器,你可以根据需要遍历字符串的每个字符,无需手动跟踪当前位置或使用索引。迭代器本质上是一个帮助我们在容器中移动并访问元素的工具。


遍历方式1

for (ite = str.begin();ite != str.end(); ite++)
{
  cout << *ite;
}

1e00ddd11f2f460caaf449558912392c.png

使用+,-运算符可以移动迭代器的位置


遍历方式2

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


37902185e8c3429ebcf7478980dac2a7.png

可以使用下标运算符进行偏移


3.迭代器失效

当我们在遍历或修改容器(例如字符串)时,迭代器可以帮助我们定位我们当前所处理的位置。然而,有些操作可能会导致迭代器失效。迭代器失效意味着先前获取的迭代器不能再安全地用于访问或修改容器中的元素。


想象一下你在一列房子前移动,每个房子都有一个门牌号(表示元素的位置)。假设你手里拿着一块纸,并且上面写着当前所处的门牌号。你可以根据纸上的门牌号找到并访问对应的房子。


然而,当进行某些操作时,例如在容器中插入或删除元素,这可能会导致房子的位置发生变化,门牌号也可能会改变。这就好像有人在你背后改变了房子的排列或增加了新的房子,导致你手里的门牌号与实际的房子位置不匹配。


在这种情况下,你手里的门牌号(即迭代器)已经失效了,不能准确地指向原来的房子。如果你继续使用失效的门牌号(迭代器),可能会导致错误的访问或修改,因为它们不再匹配实际的元素位置。


迭代器失效的情况包括:


在容器中插入或删除元素时,迭代器可能会失效。

调整容器的大小,例如重新分配内存时,迭代器可能会失效。

对容器进行排序或其他操作,可能会导致迭代器失效。

为了避免使用失效的迭代器,我们需要小心处理潜在的迭代器失效情况。一般的做法是,在进行可能导致迭代器失效的操作之后,重新获取新的迭代器来确保其有效性。


通过了解迭代器失效的原因,并谨慎处理可能导致失效的操作,我们可以更好地控制迭代器的使用,避免出现错误的访问或修改。


4.涉及到的迭代函数


1、begin()

作用:取得容器的迭代器指向容器的第一个元素。

参数:无。

返回值:迭代器,指向容器的第一个元素。


2、end()

作用:取得容器的迭代器指向容器末尾的下一个位置。

参数:无。

返回值:迭代器,指向容器末尾的下一个位置。


begin()和end()示例代码:

#include <iostream>
#include <string>
int main() {
    std::string str = "Hello";
    // Using begin() and end() to iterate over the string
    for (auto it = str.begin(); it != str.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
    return 0;
}


64c4e8a2e3f14852b4b3be2069337bf8.png

3、append

3、append( input_iterator start, input_iterator end );

作用:将指定范围内的元素添加到容器的末尾。

参数:

start:输入迭代器,指向添加元素范围的起始位置。

end:输入迭代器,指向添加元素范围的结束位置。

示例代码:

#include <iostream>
#include <string>
#include <iterator>
int main() {
    std::string str = "Hello";
    std::string input = " World";
    // 将输入字符串 " World" 的字符追加到原始字符串 "Hello"
    str.append(input.begin(), input.end());
    std::cout << str << std::endl;  // 输出结果:Hello World
    return 0;
}


2ed095cf61344563885dc9d01300abe2.png

erase函数

4、iterator erase( iterator pos );

作用:删除容器中指定位置的元素。

参数:

pos:迭代器,指向要删除的元素位置。

返回值:迭代器,指向删除元素后的位置。

示例代码:

#include <iostream>
#include <string>
int main() {
    std::string str = "Hello, World!";
    // 删除字符串中索引为6的字符(从0开始计数)
    auto erasePos = str.begin() + 6;
    str.erase(erasePos);
    std::cout << str << std::endl;  // 输出结果:Hello World!
    return 0;
}


ffce9ad85e30437cb560363603f976e9.png

5、iterator erase( iterator start, iterator end );

作用:删除容器中指定位置的元素。

参数:

pos:迭代器,指向要删除的元素位置。

返回值:迭代器,指向删除元素后的位置。

示例代码:

#include <iostream>
#include <string>
int main() {
    std::string str = "Hello, World!";
    // 删除字符串中从索引为6到索引为12的字符(左闭右开区间)
    auto eraseStart = str.begin() + 6;
    auto eraseEnd = str.begin() + 13;
    str.erase(eraseStart, eraseEnd);
    std::cout << str << std::endl;  // 输出结果:Hello!
    return 0;
}


9039768074cf46a0ac05a3887552cef6.png

insert函数

6、void insert( iterator i, size_type num, const char &ch );

作用:在指定位置前插入多个相同元素。

参数:

i:迭代器,指向插入位置。

num:要插入的元素数量。

ch:要插入的元素值。

返回值:无。

#include <iostream>
#include <string>
int main() {
    std::string str = "Hello World";
    // 在字符串的第6个位置插入3个连续的字符 '!'
    auto insertPos = str.begin() + 6;
    size_t numChars = 3;
    char ch = '!';
    str.insert(insertPos, numChars, ch);
    std::cout << str << std::endl;  // 输出结果:Hello!!! World
    return 0;
}


aa271bca17c1449287e7a16588e60e6c.png

7、void insert( iterator i, iterator start, iterator end );

作用:在指定位置插入另一个容器中给定范围的元素。

参数:

i:迭代器,指向插入位置。

start:另一个容器的迭代器,指向插入范围的起始位置。

end:另一个容器的迭代器,指向插入范围的结束位置。

返回值:无。

示例代码:

#include <iostream>
#include <string>
int main() {
    std::string str = "Hello World";
    // 在字符串的第6个位置插入 "!!!"
    auto insertPos = str.begin() + 6;
    std::string insertStr = "!!!";
    auto start = insertStr.begin();
    auto end = insertStr.end();
    str.insert(insertPos, start, end);
    std::cout << str << std::endl;  // 输出结果:Hello!!! World
    return 0;
}


85dd7675bee240ee8600a52f690eab96.png


总结


通过本文的介绍,我们了解了string迭代器的概念和使用方法。string迭代器提供了一种便捷的方式来遍历和操作字符串中的每个字符。我们可以选择合适的迭代器类型(iterator)来满足具体的需求。使用迭代器,我们可以高效地处理字符串中的字符,进行各种操作,如修改、查找、排序等。迭代器是C++ STL中非常强大且有用的特性之一,它使得我们可以更加灵活地操作数据结构。在实际编程中,我们可以充分利用string迭代器提供的功能来简化字符串的处理和操作


希望本文能够对您理解string迭代器的基础知识有所帮助。迭代器是C++ STL中的重要概念,掌握了迭代器的使用方法,可以让我们更好地利用STL提供的各种容器和算法。

相关文章
|
1天前
|
C++ 编译器 程序员
C++ 从零基础到入门(3)—— 函数基础知识
C++ 从零基础到入门(3)—— 函数基础知识
|
1天前
|
C++ 存储
C++从零基础到入门(2)—— (if、switch、for、while语句)
C++从零基础到入门(2)—— (if、switch、for、while语句)
C++从零基础到入门(2)—— (if、switch、for、while语句)
|
5天前
|
编译器 C语言 C++
C++入门基础-2
C++入门基础
12 3
|
5天前
|
C语言 C++
C++入门基础-1
C++入门基础
18 1
|
5天前
|
存储 C++ 容器
C++:STL - set & map
C++:STL - set & map
14 4
|
6天前
|
编译器 C++ Windows
【C++】vector问题解决(非法的间接寻址,迭代器失效 , memcpy拷贝问题)
不使用memcpy函数不就可以了,然后我们使用简单粗暴的赋值拷贝,这样就不会发生浅拷贝问题了!!!
16 1
|
6天前
|
编译器 C++
【C++】继续学习 string类 吧
首先不得不说的是由于历史原因,string的接口多达130多个,简直冗杂… 所以学习过程中,我们只需要选取常用的,好用的来进行使用即可(有种垃圾堆里翻美食的感觉)
7 1
|
6天前
|
算法 安全 程序员
【C++】STL学习之旅——初识STL,认识string类
现在我正式开始学习STL,这让我期待好久了,一想到不用手撕链表,手搓堆栈,心里非常爽
15 0
|
7天前
|
设计模式 安全 算法
【C++入门到精通】特殊类的设计 | 单例模式 [ C++入门 ]
【C++入门到精通】特殊类的设计 | 单例模式 [ C++入门 ]
17 0