news 2026/4/18 12:58:48

【C++】string的使用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【C++】string的使用

string类的使用

  • 一、auto 关键字:简化类型声明的利器
  • 二、string 类:更安全的字符串处理方案
    • 1、常见构造
    • 2、容量操作
    • 3、访问及遍历操作
    • 4、string 类的其他常用操作
  • 三、常用遍历
    • 1、C++11遍历
    • 2、迭代器遍历
    • 3、for遍历
  • 四、string 类的实现原理(进阶)
    • 传统写法
    • 现代写法
    • 五、string 类的实际应用场景

一、auto 关键字:简化类型声明的利器

  • 自动类型推导:无需显式指定类型,编译器根据初始化值确定变量类型
  • 简化复杂声明:对于迭代器、函数返回值等冗长类型,auto能大幅精简代码
  • 指针与引用规则
    • 声明指针时,autoauto*效果一致(如auto p = &aauto* p = &a等价)
    • 声明引用必须显式添加&(如auto& ref = a
  • 多变量声明限制:同一行声明的多个变量必须为相同类型(如auto a = 1, b = 2合法,auto a = 1, b = 2.0非法)
  • 使用限制
    • 必须在声明时初始化(无法单独声明auto x;
    • 不能作为函数参数类型(如void func(auto x)不合法)
    • 不建议作为函数返回值类型(可能导致类型模糊)
    • 不能用于声明数组(如auto arr[10]不合法)
#include<iostream>#include<typeinfo>// 需包含此头文件以使用 typeidusingnamespacestd;intgetNum(){return42;}intmain(){inta=10;autob=a;// 推导为 intautoc='a';// 推导为 charautod=getNum();// 推导为 intauto*p=&a;// 推导为 int*(与 auto p = &a 等价)auto&ref=a;// 推导为 int&// 打印推导的类型(不同编译器输出可能略有差异)cout<<"b 的类型:"<<typeid(b).name()<<endl;// intcout<<"c 的类型:"<<typeid(c).name()<<endl;// charcout<<"d 的类型:"<<typeid(d).name()<<endl;// intcout<<"p 的类型:"<<typeid(p).name()<<endl;// int*return0;}

二、string 类:更安全的字符串处理方案

C++ 标准库的string类封装了字符串的创建、修改和操作,相比 C 风格字符数组(char*),提供了自动内存管理和丰富的成员函数,是字符串处理的首选。

核心优势

  • 自动内存管理:无需手动malloc/freenew/delete,避免内存泄漏
  • 安全性:内置越界检查,减少缓冲区溢出风险
  • 丰富接口:提供拼接、查找、截取等便捷操作
  • 兼容性:支持与 C 风格字符串(const char*)相互转换
  • 动态扩展:可自动调整容量以适应字符串长度变化

1、常见构造

constructor函数名称功能说明
string()构造空字符串(默认构造)
string(const char* s)用 C 风格字符串初始化
string(const string&s)拷贝构造(复制已有 string 对象)
string(size_t n, char c)构造包含 n 个字符 c 的字符串构造包含n个字符c的string类对象
#include<string>usingnamespacestd;intmain(){string s1;// 空字符串strings2("hello");// 用 C 字符串初始化strings3(s2);// 拷贝构造strings4(5,'!');// 5个感叹号:"!!!!!"cout<<"s2: "<<s2<<endl;// 输出:hellocout<<"s4: "<<s4<<endl;// 输出:!!!!!return0;}

2、容量操作

函数名称功能说明
size返回有效字符长度(推荐使用,替代length()
empty判断字符串是否为空(为空返回true
clear清空有效字符(不释放底层内存)
reserve预留至少 n 个字符的空间(提升插入效率)
resize(n, c)调整有效字符数为 n,多余位置用 c 填充
  1. 一般情况下都是用size(),而不是length()
    2.clear()只是将string中有效字符清空,不改变底层空间大小
    3.resize(n)resize(n, c)的区别:
    - 前者将多余位置初始化为空字符(’\0’)
    - 后者将多余位置初始化为指定字符 c
    - 若n大于当前容量,会扩容;若n小于当前长度,仅截断不缩容
    4.reserve(n)仅预留空间,不改变有效字符数,n 小于当前容量时不做操作
#include<iostream>usingnamespacestd;intmain(){strings1("hello world");cout<<s1.size()<<endl;//11cout<<s1.empty()<<endl;//0s1.clear();cout<<s1<<endl;//打印空string s2;s2.reserve(100);cout<<s2.capacity()<<endl;//111//左(要初始化个数):右(初始化的字符)s2.resize(4,'c');cout<<s2<<endl;//ccccreturn0;}

3、访问及遍历操作

方式适用场景
operator[]通过下标访问(支持读写,类似数组)
begin+end正向迭代器,从首到尾遍历(适用于所有 STL 容器),begin()指向首字符,end()指向尾字符后一位
rbegin+rend反向迭代器,从尾到首遍历,rbegin()指向尾字符,rend()指向首字符前一位
范围forC++11 新增,简洁遍历所有元素(底层基于迭代器)
#include<iostream>#include<string>usingnamespacestd;intmain(){strings("hello");// 1. 下标访问cout<<"第2个字符:"<<s[1]<<endl;// 'e's[0]='H';// 修改首字符为'H'cout<<"修改后:"<<s<<endl;// Hello// 2. 正向迭代器cout<<"正向遍历:";for(autoit=s.begin();it!=s.end();++it){cout<<*it<<" ";// H e l l o}cout<<endl;// 3. 反向迭代器cout<<"反向遍历:";for(autoit=s.rbegin();it!=s.rend();++it){cout<<*it<<" ";// o l l e H}cout<<endl;// 4. 范围 for(C++11)cout<<"范围for遍历:";for(charch:s){cout<<ch<<" ";// H e l l o}cout<<endl;return0;}

4、string 类的其他常用操作

函数名称功能说明
operator+=字符串拼接(支持 string 或 C 字符串)
append()尾部追加字符串(功能类似+=
c_str()返回 C 风格字符串(const char*
find(sub, pos)从 pos 位置开始查找子串 sub,返回起始索引(未找到返回string::npos
substr(pos, len)从 pos 位置截取长度为 len 的子串(默认截取到末尾)
compare()比较与字符串 s 的大小(返回 0 表示相等)
#include<iostream>#include<string>usingnamespacestd;intmain(){string s1="hello";string s2="world";// 字符串拼接s1+=" ";s1+=s2;cout<<s1<<endl;// 输出:hello world// 查找操作size_t pos=s1.find("world");if(pos!=string::npos){cout<<"找到子串,位置:"<<pos<<endl;// 输出:6}// 截取子串string s3=s1.substr(6,5);cout<<s3<<endl;// 输出:world// C风格字符串转换constchar*cstr=s1.c_str();cout<<cstr<<endl;// 输出:hello worldreturn0;}

三、常用遍历

1、C++11遍历

适用于数组和支持下标访问的容器(如 string、vector),需要手动控制索引范围。

#include<iostream>#include<string>usingnamespacestd;intmain(){//C++98遍历intarray1[]={1,2,3,4,5};for(inti=0;i<sizeof(array1)/sizeof(array1[0]);++i){array1[i]*=2;}for(inti=0;i<sizeof(array1)/sizeof(array1[0]);++i){cout<<array1[i]<<" ";}cout<<endl;return0;}

2、迭代器遍历

迭代器是 STL 容器的通用遍历方式,适用于所有容器(包括不支持下标访问的容器如 list、map 等)
![[QQ20251203-213626.png]]

#include<iostream>#include<string>usingnamespacestd;intmain(){strings1("hello world");//正向迭代器//string::iterator it = s1.begin();autoit=s1.begin();while(it!=s1.end()){cout<<*it<<" ";++it;}cout<<endl;//反向迭代器//string::reverse_iterator rit = s1.rbegin();autorit=s1.rbegin();while(rit!=s1.rend()){cout<<*rit<<" ";++rit;}cout<<endl;conststrings2("hello world");//const正向迭代器//string::const_iterator cit = s2.begin();autocit=s2.begin();while(cit!=s2.end()){cout<<*cit<<" ";++cit;}cout<<endl;//const反向迭代器//string::const_reverse_iterator rcit = s2.rbegin();autorcit=s2.rbegin();while(rcit!=s2.rend()){cout<<*rcit<<" ";++rcit;}return0;}

3、for遍历

一种简洁的遍历方式,自动迭代容器中所有元素,底层基于迭代器实现。语法格式:

for(元素类型 变量名:容器名){// 循环体}
#include<iostream>#include<string>usingnamespacestd;intmain(){// 数组遍历intarray2[]={1,2,3,4,5};for(auto&e:array2)// 使用引用避免拷贝,支持修改元素e*=2;for(autoe:array2)cout<<e<<" ";// 输出:2 4 6 8 10cout<<endl;// 字符串遍历stringstr("hello world");for(autoch:str){cout<<ch<<" ";// 输出:h e l l o w o r l d}cout<<endl;return0;}

四、string 类的实现原理(进阶)

了解 string 类的实现有助于更好地理解其特性,下面展示两种经典的实现方式:

传统写法

通过显式分配和释放内存实现深拷贝,确保每个对象拥有独立的字符串资源:

classString{public:// 构造函数String(constchar*str=""){if(nullptr==str){assert(false);return;}_str=newchar[strlen(str)+1];// 分配空间(包含结束符)strcpy(_str,str);// 拷贝内容}// 拷贝构造函数String(constString&s):_str(newchar[strlen(s._str)+1]){strcpy(_str,s._str);}// 赋值运算符重载String&operator=(constString&s){if(this!=&s)// 避免自赋值{char*pStr=newchar[strlen(s._str)+1];strcpy(pStr,s._str);delete[]_str;// 释放旧空间_str=pStr;// 指向新空间}return*this;}// 析构函数~String(){if(_str){delete[]_str;_str=nullptr;}}private:char*_str;// 存储字符串};

现代写法

通过交换临时对象的资源简化代码,利用临时对象的生命周期自动释放内存

classString{public:// 构造函数String(constchar*str=""){if(nullptr==str){assert(false);return;}_str=newchar[strlen(str)+1];strcpy(_str,str);}// 拷贝构造函数(现代写法)String(constString&s):_str(nullptr){StringstrTmp(s._str);// 创建临时对象swap(_str,strTmp._str);// 交换资源}// 赋值运算符重载(现代写法)String&operator=(String s)// 传值参数会触发拷贝构造{swap(_str,s._str);// 交换资源,临时对象会自动释放旧资源return*this;}// 析构函数~String(){if(_str){delete[]_str;_str=nullptr;}}private:char*_str;};

五、string 类的实际应用场景

  1. 文本处理:日志记录、配置文件解析、字符串格式化
  2. 用户交互:命令行输入输出、GUI 文本控件
  3. 网络编程:HTTP 协议处理、数据报文组装与解析
  4. 文件操作:路径处理、文件内容读写
  5. 数据转换:数值与字符串的相互转换
    掌握autostring是 C++ 开发的基础,合理使用能显著提升代码简洁性和安全性。实际开发中,建议优先使用标准库提供的string而非 C 风格字符串,减少内存管理风险。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 8:38:28

15分钟精通DuckDB:嵌入式分析数据库实战指南

15分钟精通DuckDB&#xff1a;嵌入式分析数据库实战指南 【免费下载链接】duckdb DuckDB is an in-process SQL OLAP Database Management System 项目地址: https://gitcode.com/GitHub_Trending/du/duckdb 在当今数据驱动的时代&#xff0c;传统数据库的复杂部署和维护…

作者头像 李华
网站建设 2026/4/18 8:50:42

CesiumJS终极指南:从零开始构建3D地球可视化应用

CesiumJS终极指南&#xff1a;从零开始构建3D地球可视化应用 【免费下载链接】cesium An open-source JavaScript library for world-class 3D globes and maps :earth_americas: 项目地址: https://gitcode.com/GitHub_Trending/ce/cesium 在当今数据驱动的世界中&…

作者头像 李华
网站建设 2026/4/18 7:54:39

Remote DOM:彻底改变Web应用安全与性能的前沿技术

Remote DOM&#xff1a;彻底改变Web应用安全与性能的前沿技术 【免费下载链接】remote-ui 项目地址: https://gitcode.com/gh_mirrors/re/remote-ui 在当今Web开发领域&#xff0c;Remote DOM正以其革命性的架构设计&#xff0c;为前端应用的安全性和性能优化开辟了全新…

作者头像 李华
网站建设 2026/4/18 7:58:09

如何选择最佳错误监控方案:Apache SkyWalking vs Sentry实战指南

如何选择最佳错误监控方案&#xff1a;Apache SkyWalking vs Sentry实战指南 【免费下载链接】skywalking APM, Application Performance Monitoring System 项目地址: https://gitcode.com/gh_mirrors/sky/skywalking 当系统出现异常时&#xff0c;你是否曾面临这样的困…

作者头像 李华
网站建设 2026/4/18 3:32:26

ComfyUI-Manager安全配置实战指南:从入门到精通

ComfyUI-Manager安全配置实战指南&#xff1a;从入门到精通 【免费下载链接】ComfyUI-Manager 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-Manager 当你在使用ComfyUI-Manager时&#xff0c;是否遇到过"操作被安全级别阻止"的提示&#xff1f;这恰…

作者头像 李华
网站建设 2026/4/17 17:18:09

EmotiVoice语音合成引擎的商业化落地案例分享

EmotiVoice语音合成引擎的商业化落地案例分享 在虚拟主播直播间里&#xff0c;一条“哥哥加油&#xff01;”的弹幕刚刷出不到300毫秒&#xff0c;屏幕上的数字人便带着笑意回应——声音不仅符合角色设定&#xff0c;情绪也恰到好处地传递出被鼓励后的温暖。这背后&#xff0c;…

作者头像 李华