【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++数据结构】string的模拟实现
【C++数据结构】string的模拟实现
|
29天前
|
NoSQL 安全 Java
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
这篇文章深入探讨了Redis中的String数据类型,包括键操作的命令、String类型的命令使用,以及String在Redis中的内部数据结构实现。
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
|
20天前
|
编译器 C++ 容器
【C++】String常见函数用法
【C++】String常见函数用法
13 1
|
13天前
|
存储 C++
C++(五)String 字符串类
本文档详细介绍了C++中的`string`类,包括定义、初始化、字符串比较及数值与字符串之间的转换方法。`string`类简化了字符串处理,提供了丰富的功能如字符串查找、比较、拼接和替换等。文档通过示例代码展示了如何使用这些功能,并介绍了如何将数值转换为字符串以及反之亦然的方法。此外,还展示了如何使用`string`数组存储和遍历多个字符串。
|
22天前
|
存储 C++
C++ dll 传 string 类 问题
C++ dll 传 string 类 问题
16 0
|
27天前
|
存储 C++
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
30 0
|
1月前
|
存储 算法 程序员
【STL】string
【STL】string
|
1月前
|
编译器 C语言 C++
【C++】模拟实现string类
【C++】模拟实现string类
|
3月前
|
Java UED
Java中String强转int:一种常见的错误和解决方法
在Java中将非数字字符串转换为整数会导致`NumberFormatException`。要解决这个问题,可以使用`try-catch`捕获异常,正则表达式验证数字格式,或利用异常信息提供错误提示。例如,`Integer.parseInt()`会因遇到非数字字符如`&quot;123abc&quot;`而抛出异常,但通过异常处理或正则`\\d+`可确保安全转换。记得在编程时避免直接强转,以防止程序异常中断。
|
1月前
|
前端开发 Java
成功解决:java.lang.String cannot be cast to java.lang.Integer
这篇文章记录了作者在使用Axios二次封装时遇到的一个Java类型转换问题,即前端传递的字符串参数不能直接转换为Integer类型,文章提供了正确的转换方法来解决这个问题。
成功解决:java.lang.String cannot be cast to java.lang.Integer