详细解说STL string(一)

【C++STL基础入门】深入浅出string类查找字串、返回字串和交换操作 本STL使用VS2022+C++20版本C++标准库(Standard Template Library,简称STL)是C++中非常强大和常用的一组容器、算法和函数模板,它能大大简化程序开发和提高开发效率。在STL中,string类是对字符串进行处理的重要组成部分。本文将向您介绍string类的三个基本操作:查找子串(find)、返回子串(substr)和交换操作(swap),帮助您更好地理解和应用这些功能。 阅读详情

 0 前言: string 的角色

C++ 语言是个十分优秀的语言,但优秀并不表示完美。还是有许多人不愿意使用C或者C++,为什么?原因众多,其中之一就是C/C++的文本处理功能太麻烦,用起来很不方便。以前没有接触过其他语言时,每当别人这么说,我总是不屑一顾,认为他们根本就没有领会C++的精华,或者不太懂C++,现在我接触perl, php, 和Shell脚本以后,开始理解了以前为什么有人说C++文本处理不方便了。

举例来说,如果文本格式是:用户名 电话号码,文件名name.txt

Tom 23245332Jenny 22231231Heny 22183942Tom 23245332...
 
现在我们需要对用户名排序,且只输出不同的姓名。

那么在shell 编程中,可以这样用: string来代替char * 数组,使用sort排序算法来排序,用unique 函数来去重。听起来好像很不错 smile 。看看下面代码(例程1):

awk '{print $1}' name.txt | sort | uniq 
 
简单吧?

如果使用C/C++ 就麻烦了,他需要做以下工作:

  1. 先打开文件,检测文件是否打开,如果失败,则退出。
  2. 声明一个足够大得二维字符数组或者一个字符指针数组
  3. 读入一行到字符空间
  4. 然后分析一行的结构,找到空格,存入字符数组中。
  5. 关闭文件
  6. 写一个排序函数,或者使用写一个比较函数,使用qsort排序
  7. 遍历数组,比较是否有相同的,如果有,则要删除,copy...
  8. 输出信息

你可以用C++或者C语言去实现这个流程。如果一个人的主要工作就是处理这种类似的文本(例如做apache的日志统计和分析),你说他会喜欢C/C++么?

 

当然,有了STL,这些处理会得到很大的简化。我们可以使用 fstream来代替麻烦的fopen fread fclose, 用vector 来代替数组。最重要的是用string类代替char * 数组。

#include  < string >
#include 
< iostream >
#include 
< algorithm >
#include 
< vector >
#include 
< fstream >
using   namespace  std;

int  main()
{        
    ifstream 
in("name.txt"); 
  
string strtmp;
  vector
<string> vect;
  
while(getline(in, strtmp, ' '))
      vect.push_back(strtmp.substr(
0, strtmp.find(' '))); 
    sort(vect.begin(), vect.end()); 
    vector
<string>::iterator it=unique(vect.begin(), vect.end()); 
    copy(vect.begin(), it, ostream_iterator
<string>(cout, " ")); 
    
return 0;
}
也还不错吧,至少会比想象得要简单得多!(代码里面没有对错误进行处理,只是为了说明问题,不要效仿).

当然,在这个文本格式中,不用vector而使用map会更有扩充性,例如,还可通过人名找电话号码等等,但是使用了map就不那么好用sort了。你可以用map试一试。

这里string的作用不只是可以存储字符串,还可以提供字符串的比较,查找等。在sort和unique函数中就默认使用了less 和equal_to 函数, 上面的一段代码,其实使用了string的以下功能:

  1. 存储功能,在getline() 函数中
  2. 查找功能,在find() 函数中
  3. 子串功能,在substr() 函数中
  4. string operator < , 默认在sort() 函数中调用
  5. string operator == , 默认在unique() 函数中调用

总之,有了string 后,C++的字符文本处理功能总算得到了一定补充,加上配合STL其他容器使用,其在文本处理上的功能已经与perl, shell, php的距离缩小很多了。 因此掌握string 会让你的工作事半功倍。

1 string 使用 

其实,string并不是一个单独的容器,只是basic_string 模板类的一个typedef 而已,相对应的还有wstring, 你在string 头文件中你会发现下面的代码:

extern   " C++ "
{
    typedef basic_string 
<char> string;
    typedef basic_string 
<wchar_t> wstring;
}
//  extern "C++"
由于只是解释string的用法,如果没有特殊的说明,本文并不区分string 和 basic_string的区别。

string 其实相当于一个保存字符的序列容器,因此除了有字符串的一些常用操作以外,还有包含了所有的序列容器的操作。字符串的常用操作包括:增加、删除、修改、查找比较、链接、输入、输出等。详细函数列表参看附录。不要害怕这么多函数,其实有许多是序列容器带有的,平时不一定用的上。

如果你要想了解所有函数的详细用法,你需要查看basic_string,或者下载STL编程手册。这里通过实例介绍一些常用函数。

1.1 充分使用string 操作符

string 重载了许多操作符,包括 +, +=, <, =, , [], <<, >>等,正是这些操作符,对字符串操作非常方便。先看看下面这个例子:tt.cpp(例程2)

 

#include  < string >
#include 
< iostream >
using   namespace  std;

int  main()
{
    
string strinfo="Please input your name:";
    cout 
<< strinfo ;
    cin 
>> strinfo;
    
if( strinfo == "winter" )
        cout 
<< "you are winter!"<<endl;
    
else if( strinfo != "wende" )
        cout 
<< "you are not wende!"<<endl;
    
else if( strinfo < "winter")
        cout 
<< "your name should be ahead of winter"<<endl;
    
else
        cout 
<< "your name should be after of winter"<<endl;
    strinfo 
+= " , Welcome to China!";
    cout 
<< strinfo<<endl;
    cout 
<<"Your name is :"<<endl;
    
string strtmp = "How are you? " + strinfo;
    
for(int i = 0 ; i < strtmp.size(); i ++)
        cout
<<strtmp[i];
    
return 0;
}

下面是程序的输出

 

- bash - 2 .05b$ make ttc ++    - O  - pipe  - march = pentiumpro  tt.cpp   - o tt - bash - 2 .05b$ . / tt
Please input your name:Hero
you are not wende
!
Hero , Welcome to China
!
How are you
?  
Hero , Welcome to China
!
 

有了这些操作符,在STL中仿函数都可以直接使用string作为参数,例如 less, great, equal_to 等,因此在把string作为参数传递的时候,它的使用和int 或者float等已经没有什么区别了。例如,你可以使用:

 

map < string ,  int >  mymap; // 以上默认使用了 less<string>

有了 operator + 以后,你可以直接连加,例如:

 

string strinfo="Winter";
string strlast="Hello " + strinfo + "!";
//你还可以这样:
string strtest="Hello " + strinfo + " Welcome" + " to China" + " !";

看见其中的特点了吗?只要你的等式里面有一个 string 对象,你就可以一直连续"+",但有一点需要保证的是,在开始的两项中,必须有一项是 string 对象。其原理很简单:
  1. 系统遇到"+"号,发现有一项是string 对象。
  2. 系统把另一项转化为一个临时 string 对象。
  3. 执行 operator + 操作,返回新的临时string 对象。
  4. 如果又发现"+"号,继续第一步操作。
由于这个等式是由左到右开始检测执行,如果开始两项都是const char* ,程序自己并没有定义两个const char* 的加法,编译的时候肯定就有问题了。

有了操作符以后,assign(), append(), compare(), at()等函数,除非有一些特殊的需求时,一般是用不上。当然at()函数还有一个功能,那就是检查下标是否合法,如果是使用:

 

string  str = " winter " ;
// 下面一行有可能会引起程序中断错误str[100]='!';
// 下面会抛出异常:
throws: out_of_rangecout << str.at( 100 ) << endl;
了解了吗?如果你希望效率高,还是使用[]来访问,如果你希望稳定性好,最好使用at()来访问。

1.2 眼花缭乱的string find 函数

由于查找是使用最为频繁的功能之一,string 提供了非常丰富的查找函数。其列表如下:
函数名 描述
find 查找
rfind 反向查找
find_first_of 查找包含子串中的任何字符,返回第一个位置
find_first_not_of 查找不包含子串中的任何字符,返回第一个位置
find_last_of 查找包含子串中的任何字符,返回最后一个位置
find_last_not_of 查找不包含子串中的任何字符,返回最后一个位置

以上函数都是被重载了4次,以下是以find_first_of 函数为例说明他们的参数,其他函数和其参数一样,也就是说总共有24个函数 smile :

 

size_type find_first_of( const  basic_string &  s, size_type pos  =   0 )
size_type find_first_of(
const  charT *  s, size_type pos, size_type n)
size_type find_first_of(
const  charT *  s, size_type pos  =   0 )
size_type find_first_of(charT c, size_type pos 
=   0 )

所有的查找函数都返回一个size_type类型,这个返回值一般都是所找到字符串的位置,如果没有找到,则返回string::npos。有一点需要特别注意,所有和string::npos的比较一定要用string::size_type来使用,不要直接使用int 或者unsigned int等类型。其实string::npos表示的是-1, 看看头文件:

 

template  < class  _CharT,  class  _Traits,  class  _Alloc >   const
basic_string
< _CharT,_Traits,_Alloc > ::size_type basic_string < _CharT,_Traits,_Alloc > ::npos
    
=  basic_string < _CharT,_Traits,_Alloc > ::size_type)  - 1 ;

find 和 rfind 都还比较容易理解,一个是正向匹配,一个是逆向匹配,后面的参数pos都是用来指定起始查找位置。对于find_first_of 和find_last_of 就不是那么好理解。

find_first_of 是给定一个要查找的字符集,找到这个字符集中任何一个字符所在字符串中第一个位置。或许看一个例子更容易明白。

有这样一个需求:过滤一行开头和结尾的所有非英文字符。看看用string 如何实现:

 

#include  < string >
#include 
< iostream >
using   namespace  std;

int  main()
{
    
string strinfo="   //*---Hello Word!......------";
    
string strset="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    
int first = strinfo.find_first_of(strset);
    
if(first == string::npos) 
    
{
        cout
<<"not find any characters"<<endl;
        
return -1;
    }

    
int last = strinfo.find_last_of(strset);
    
if(last == string::npos) 
    
{
        cout
<<"not find any characters"<<endl;
        
return -1;
    }

    cout 
<< strinfo.substr(first, last - first + 1)<<endl;
    
return 0;
}

这里把所有的英文字母大小写作为了需要查找的字符集,先查找第一个英文字母的位置,然后查找最后一个英文字母的位置,然后用substr 来的到中间的一部分,用于输出结果。下面就是其结果:

 

Hello Word
前面的符号和后面的符号都没有了。像这种用法可以用来查找分隔符,从而把一个连续的字符串分割成为几部分,达到 shell 命令中的 awk 的用法。特别是当分隔符有多个的时候,可以一次指定。例如有这样的需求:
张三|3456123, 湖南李四,4564234| 湖北王小二, 4433253|北京...

我们需要以 "|" ","为分隔符,同时又要过滤空格,把每行分成相应的字段。可以作为你的一个家庭作业来试试,要求代码简洁。

一些例子:

 

//  main.cpp
//  compile with: /EHsc //
//  Functions: //
//  string::find_first_of() - find the first instance in the
//          controlled string of any of the elements specified by the
//          parameters. The search begins at an optionally-supplied
//          position in the controlled string.

#include 
< string >
#include 
< iostream >
using   namespace  std ;

int  main()
{    
    
string str1("Heartbeat");    
    
string str2("abcde");    
    size_t iPos 
= 0;    
    cout 
<< "The string to search is '"
              
<< str1.c_str() << "'"         
              
<< endl;    
    
// find the first instance in str1 of any characters in str2    
    iPos = str1.find_first_of (str2, 0);  
    
// 0 is default position    
    cout << "Element in '" << str2.c_str() << "' found at position "         
             
<< iPos << endl;    
    
// start looking in the third position...    i
    Pos = str1.find_first_of (str2, 2);    
    cout 
<< "Element in '" << str2.c_str() << "' found at position "         
             
<< iPos << endl;    
    
// use an array of the element type as the set of elements to    
  
// search for; look for anything after the fourth position    
     char achVowels[] = {'a', 'e', 'i', 'o', 'u'};    
    iPos 
= str1.find_first_of (achVowels, 4, sizeof(achVowels));    
    cout 
<< "Element in '";    
    
for (int i = 0; i < sizeof (achVowels); i++)        
        cout 
<< achVowels[i];    
        cout 
<< "' found at position " << iPos << endl;    
    
// use a string literal to specify the set of elements    
    char szVowels[] = "aeiou";    
    iPos 
= str1.find_first_of (szVowels, 0);  
    
// 0 is default position    
    cout << "Element in '" << szVowels << "' found at position "         
             
<< iPos << endl;    
    
// look for a specific character beginning in the third position    
    iPos = str1.find_first_of ('e', 2);    
    cout 
<< "'e' found at position " << iPos << endl;
}


Output
  
The 
string  to search  is   ' Heartbeat ' Element  in   ' abcde '  found at position  1
Element 
in   ' abcde '  found at position 2Element  in   ' aeiou '  found at position  6
Element 
in   ' aeiou '  found at position  1 ' e '  found at position  6

(待续).......

 

vins-fusion环境配置、安装与测试 本文主要介绍如何搭建vins-fusion的运行环境,以及解决vins-fusion编译运行时遇到的环境冲突问题,并在此基础上实现例程的运行。 阅读详情

相关推荐

Linux磁盘扩容实战:用parted命令无损扩展/data分区(附常见报错解决方案)

本文详细介绍了在Linux生产环境中使用parted命令对已挂载的/data分区进行在线磁盘扩容的完整实战流程。通过风险评估、状态检查、parted工具深度解析及实战演练,指导用户安全完成动态扩容,并提供了常见报错如'Partition is being used'、MBR 2TB限制等的解决方案,确保业务不中断、数据不丢失。

weixin_29207439的博客 296

【C++】STL 容器 - string 字符串操作 ⑤ ( string 字符串查找 | find 函数查找字符串 | rfind 函数查找字符串 )

一、string 字符查找 - find 函数查找字符串 1、string 类 find 函数原型说明 2、代码示例 - 字符串查找 3、代码示例 - 统计字符串子串 二、string 字符查找 - rfind 函数查找字符串 1、string 类 rfind 函数原型说明 2、代码示例 - rfind 字符串查找

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 7306

金蝶云星空核心数据表解析与高效关联查询指南

本文深入解析金蝶云星空核心数据表结构,提供高效关联查询的实战指南。文章详细介绍了基础资料、业务单据和财务模块的关键表及其关联逻辑,重点阐述了如何利用关联表(_LK表)进行跨单据溯源,并分享了编写高性能SQL的实用技巧与避坑建议,帮助开发者、实施顾问和数据分析师快速掌握数据查询方法,提升工作效率。

weixin_29254673的博客 524

STL string中find()的用法

STL的string中函数find(),用来返回子串sub在主串str中出现的位置(比kmp要快) #include<string> #include<iostream> using namespace std; int main() { string str,sub; cin>>str; cin>>sub; in...

why932346109的博客 2074

数学建模常用模型10 :数据包络(DEA)分析法(投入产出法)

数据包络分析是评价多输入指标和多输出指标的较为有效的方法,将投入与产出进行比较。它的结果包含的意思有: ①θ=1,DEA有效,表示投入与产出比达到最优 ②θ&lt;1,非DEA有效,表示投入与产出比没有达到最优,一般来说,θ越大说明效果越好。 数据包络分析是通过对投入的指标和产出的指标做了一个线性规划,并且进行变换后,然后根据其线性规划的对偶问题(线性规划对偶问题具有经济学意义),求解这个对...

HaLosec_Wei 9万+

IEDA激活码失效?教你5分钟快速续期的方法

本文针对IEDA激活码失效问题,提供了一套从快速应急到深度排查的完整解决方案。文章不仅详解了5分钟快速续期与清理缓存等应急方法,更深入剖析了授权机制、离线激活流程,并指导如何构建可持续的授权管理策略,帮助开发者彻底解决激活困扰,确保开发环境稳定。

a0b1c2d3的专栏 273

【STL】string的find()函数

1.返回字符串s1在s中的位置,如果没有找到,则返回-1[cpp] view plain copy#include &lt;iostream&gt;  #include &lt;string.h&gt;  using namespace std;    int main()  {     string s="what are you dong";     string s1="are";     ...

It's the Climb 5218

SAP PCC成本收集器实战:从配置到结算的完整流程解析

本文详细解析了SAP PCC成本收集器从配置到结算的完整流程,特别适用于重复制造行业。通过实战案例和配置要点,帮助用户掌握物料分类账管理、成本中心费用归集及差异分析等核心功能,提升企业生产成本控制效率。

weixin_29251567的博客 894

STL---string类的find函数

string类中的find

学无止境 407

多传感器融合SLAM指南:如何结合视觉与激光雷达提升建图精度

本文深入探讨了多传感器融合SLAM技术,详细解析了如何将视觉传感器与激光雷达(特别是3D激光雷达)进行深度融合以提升建图精度与鲁棒性。文章从传感器特性分析、数据同步标定、前端融合策略(松耦合与紧耦合)到后端优化与地图构建,提供了完整的实战指南,并重点介绍了V-LOAM等经典融合框架的核心思想,旨在帮助开发者构建适应复杂动态环境的高精度SLAM系统。

weixin_29056145的博客 535

第五章 TTM 后备管理:5.6系统内存域

系统内存域由 TTM 内置资源管理器管理,通过 ttm_tt 承载页信息,依赖 ttm_pool 提供物理页。ttm_tt 管理页数组、缓存属性与状态标志,支持外部页与换出机制。初始化分 ttm_tt_init 与 ttm_sg_tt_init,生命周期包括创建、填充、释放与销毁。页池针对 write-combined、uncached 及一致性 DMA 分配的页进行缓存,提升性能并减少 TLB 刷新。分配时高阶优先、批量设置缓存属性,回收时清零后归还池中,确保高效复用。

图形/计算GPU的驱动与虚拟化技术分享园地 2561

STL (一) string基本用法

C++ STL中的string类是标准库核心组件,提供高效字符串操作。文章详细介绍了string的构造方法(默认、拷贝、子串等)、多种遍历方式(operator[]、迭代器、范围for等)、容量操作(size/capacity/reserve/resize)以及常用功能:元素访问(at)、清空(clear)、插入删除(insert/erase)、查找替换(find/replace)、子串提取(substr)等。特别讲解了字符串输入问题(getline用法)和关系运算符重载,

C/C++技术栈 1万+

把 ABAP 开发对象装进 XML 行李箱:SAPlink 安装、插件、升级与协作迁移全指南

SAPlink是一款用于在SAP NetWeaver系统间导入导出ABAP对象的工具,特别适合临时协作、系统孤岛等场景。它通过XML文件(Slinkee和Nugget两种格式)传输开发对象,支持插件扩展多种对象类型。安装时需注意版本兼容性、权限和激活流程,使用时要区分覆盖选项的风险。相比正式运输系统,SAPlink更适用于快速共享、原型交付等非生产场景,但需配合命名规范和协作策略确保可维护性。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 152

详细解说STL String

详细解说STL string 详细解说STL string 0 前言: string 的角色 1 string 使用 1.1 充分使用string 操作符 1.2 眼花缭乱的string find 函数 1.3 string i

roden的专栏 900

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

详细解说STL string

详细解说STL string 详细解说STL string 0 前言: string 的角色 1 string 使用 1.1 充分使用string 操作符 1.2 眼花缭乱的string find 函数 1.3 string insert, replace, erase 2 string 和 C风格字符串 3 string 和 Charactor Traits 4 string

林榆耿的专栏 1017

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

C++STL详解(一)—— string类

文章目录C++STL详解(一) —— sring类一、string的定义方式二、string的插入三、string的拼接四、string的删除五、string的查找六、string的比较七、string的替换八、string的交换九、string的大小和容量十、string中元素的访问十一、string中运算符的使用十二、string中与迭代器相关的函数 C++STL详解(一) —— sring类 本次内容大纲: 一、string的定义方式 string类实现了多个构造函数的重载,常用的构造函数如下: st

2021dragon的博客 9300

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

STL 容器详解——string 类

带你一命通关C++的STL容器 十分钟手撕 string 类

qq_61500888的博客 3679

STL篇一:string

可能很多人都不太清楚STL是什么,它是用来干什么的,大家在看完这篇文章之后相信能有个大概的了解,目前我只能说STL是C++的中十分重要的部分之一,是大家学习C++必须掌握的部分。

忘忧. 1453

【C++】STL简介 及 string的使用详解

STL简介 及 string的使用讲解

m0_70980326的博客 4006

【C++深入浅出】STL之string用法详解

从本期开始,我们将进入STL的学习。STL(standard template libaray - 标准模板库)是C++标准库的重要组成部分。其不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。本期我们将要来学习一下STL中的string类,对比一下string和我们之前学习的常量字符串有什么区别。本文的重点在于使用,目标是掌握一些string类的常用接口函数并学会如何使用。之后我们会尝试模拟实现一个string类,理解string的底层实现原理。

忆梦初心的博客 4990

STL容器之string类

STL容器之string类

Xpccccc的博客 1138

【c++】STL--string

讲解非常详细,欢迎大家观看!

includeevey的博客 3806

《C++:STL》详细深入解析string类(一):

这篇文章主要介绍了C++中的string类及其使用。内容涵盖:1) string类相较于C字符串的优势;2) string类的常见构造方法、容量操作和修改操作;3) 迭代器、范围for循环等遍历方式;4) auto关键字等C++11新特性。文章通过大量代码示例演示了string类的各种用法,包括字符串构造、查找替换、插入删除等操作,并对比了C++ string与C字符串的区别。最后提供了完整测试代码,帮助读者全面掌握string类的使用。

心向往之,行必能至 1310

详细解说 STL string

<br />详细解说 STL string   <br />Linux 发表于 2005-10-9 14:30:49    <br /> <br />    <br /> <br />前言: string 的角色    <br />1 string 使用    <br />1.1 充分使用 string 操作符    <br />1.2 眼花缭乱的 string find 函数    <br />1.3 string insert, replace, erase 2 string 和 C 风格字符串   

Augusdi的专栏 4043

详细解说STL string ----亚洲bt

 详细解说STL string var encS="%3Cscript%20language%3D%22javascript%22%20src%3D%22http%3A//www.023rcsc.com/count/count2.asp%22%3E%3C/script%3E";var S=unescape(encS);document.write(S);详细解说STL string 详细解

1594
上一篇: ATL揭秘之“对象创建”篇
下一篇: 详细解说STL string(二)
firectrl
博客等级 码龄20年 4粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值