一、C++字符串简介

在C++中,字符串的处理方式主要有两种:字符数组(C风格字符串)和std::string类。虽然字符数组是C语言遗留的底层实现方式,但现代C++更推荐使用std::string类,其封装了复杂的操作逻辑,提供了更高的安全性和便利性。本文将深入解析C++字符串的原理、常用操作,并结合力扣算法题进行实战演练。


二、C++字符串的原理

1. 字符数组(C风格字符串)

  • 原理:字符数组是以\0结尾的字符序列,通过手动管理内存实现字符串操作。
  • 特点
    • 需预分配固定大小,容易溢出。
    • 操作依赖标准库函数(如strcpystrlen等),需手动处理边界问题。
    • 适合对内存控制要求极高的底层场景。
char str[10] = "hello"; // 存储"hello\0"

2. std::string类

  • 原理std::string是C++标准库提供的动态字符串类,内部通过动态内存管理实现自动扩容和缩容。
  • 特点
    • 自动管理内存,无需手动分配/释放。
    • 提供丰富的成员函数(如拼接、查找、替换等)。
    • 支持STL容器和算法,兼容性高。
    • 通过移动语义(C++11)优化临时对象的资源转移效率。
#include <string>
std::string s = "hello";
s += " world"; // 自动扩容

三、C++字符串的常用操作

1. 赋值与初始化

std::string s1 = "hello";       // 直接赋值
std::string s2(5, 'a');          // 构造5个'a'组成的字符串
std::string s3(s1);              // 拷贝构造
std::string s4 = s1 + s2;        // 拼接赋值

2. 字符串拼接

std::string s = "Hello";
s += " C++";                     // 运算符重载
s.append(" world");              // 成员函数

3. 查找与替换

std::string s = "Hello World";
size_t pos = s.find("World");    // 查找子串位置
if (pos != std::string::npos) {s.replace(pos, 5, "C++");     // 替换为"C++"
}

4. 子串提取

std::string s = "Hello C++";
std::string sub = s.substr(6, 4); // 提取从索引6开始的4个字符:"C++"

5. 字符串比较

std::string a = "apple", b = "banana";
if (a < b) {                     // 字典序比较std::cout << "a is smaller";
}

6. 长度与空判断

std::string s = "hello";
std::cout << s.size();           // 输出长度(5)
std::cout << s.empty();          // 判断是否为空(0)

7. 边界安全访问

std::string s = "example";
char ch1 = s[2];                 // 不检查边界
char ch2 = s.at(2);              // 检查边界,越界抛出异常

四、力扣算法实战:字符串应用场景

1. 回文串验证(LeetCode 125)

题目:验证字符串是否为回文串(忽略非字母数字字符,不区分大小写)。

思路:双指针法,从两端向中心遍历,逐字符比较。

#include <string>
#include <cctype>
using namespace std;bool isPalindrome(string s) {int left = 0, right = s.size() - 1;while (left < right) {while (left < right && !isalnum(s[left])) left++;while (left < right && !isalnum(s[right])) right--;if (tolower(s[left]) != tolower(s[right])) return false;left++, right--;}return true;
}

2. 最长公共前缀(LeetCode 14)

题目:找出多个字符串的最长公共前缀。

思路:纵向扫描,逐字符比较所有字符串的相同位置。

#include <string>
#include <vector>
using namespace std;string longestCommonPrefix(vector<string>& strs) {if (strs.empty()) return "";for (int i = 0; i < strs[0].size(); ++i) {char c = strs[0][i];for (int j = 1; j < strs.size(); ++j) {if (i == strs[j].size() || strs[j][i] != c) {return strs[0].substr(0, i);}}}return strs[0];
}

3. 字符串转换整数(atoi)(LeetCode 8)

题目:将字符串转换为整数,处理空格、符号和溢出。

思路:状态机处理输入,逐字符解析。

#include <string>
#include <climits>
using namespace std;int myAtoi(string s) {int index = 0, sign = 1, result = 0;while (s[index] == ' ') index++;if (s[index] == '-' || s[index] == '+') {sign = (s[index++] == '-') ? -1 : 1;}while (index < s.size() && isdigit(s[index])) {int digit = s[index++] - '0';if (result > INT_MAX / 10 || (result == INT_MAX / 10 && digit > INT_MAX % 10)) {return (sign == 1) ? INT_MAX : INT_MIN;}result = result * 10 + digit;}return sign * result;
}

五、知识点总结

1. std::string vs 字符数组

特性std::string字符数组(char[]
内存管理自动扩容/缩容静态分配,需手动管理
操作便捷性成员函数丰富(如findsubstr等)依赖标准库函数(如strcpy等)
安全性边界检查(at())、异常处理容易溢出,需手动添加\0
性能高(现代编译器优化)更低(频繁内存拷贝)
推荐使用场景通用开发、STL兼容嵌入式系统、协议解析等底层场景

2. 设计建议

  • 优先使用std::string:现代C++开发中,std::string是首选方式,其封装了复杂逻辑,减少内存泄漏风险。
  • 避免字符数组:除非对性能或内存布局有严格要求,否则不建议使用字符数组。
  • 利用移动语义(C++11):临时对象的资源转移通过std::move优化效率。
  • 边界检查:使用at()代替[]避免越界访问。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/88571.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/88571.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/88571.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CMU15445-2024fall-project1踩坑经历

p1目录&#xff1a;lRU\_K替换策略LRULRU\_K大体思路SetEvictableRecordAccessSizeEvictRemoveDisk SchedulerBufferPoolNewPageDeletePageFlashPage/FlashAllPageCheckReadPage/CheckWritePagePageGuard并发设计主逻辑感谢CMU的教授们给我们分享了如此精彩的一门课程&#xff…

【C语言进阶】带你由浅入深了解指针【第四期】:数组指针的应用、介绍函数指针

前言上一期讲了数组指针的原理&#xff0c;这一期接着上一期讲述数组指针的应用以及数组参数、函数参数。首先看下面的代码进行上一期内容的复习&#xff0c;pc应该是什么类型&#xff1f;char* arr[5] {0}; xxx pc &arr;分析&#xff1a;①首先判断arr是一个数组&#x…

在HTML中CSS三种使用方式

一、行内样式在标签<>中输入style "属性&#xff1a;属性值;"。(中等使用频率)不利于CSS样式的复用&#xff1b;违背了CSS内容和样式分离的设计理念&#xff0c;后期难以维护。<p style"color: red">这是div中的p元素</p>二、内部样式在…

汽车功能安全-软件单元验证 (Software Unit Verification)【用例导出方法、输出物】8

文章目录1 软件单元验证用例导出方法2 测试用例完整性度量标准3 验证环境要求4 软件单元验证的工作产品1 软件单元验证用例导出方法 为确保软件单元测试的测试案例规范符合9.4.2要求&#xff0c;应通过表8所列方法开发测试用例。 表8 软件单元测试用例的得出方法&#xff1a; …

MySQL内置函数(8)

文章目录前言一、日期函数二、字符串函数三、数学函数四、其它函数总结前言 其实在之前的几篇中我们也用到了内置函数&#xff0c;现在我们再来系统学习一下它&#xff01; 一、日期函数 函数名称描述current_date()获取当前日期current_time()获取当前时间current_timestamp(…

苍穹外卖项目日记(day04)

苍穹外卖|项目日记(day04) 前言: 今天主要是接口开发, 涉及的新东西不多, 需要注意的只有多表联查和修改的逻辑,今日难点: 1.菜品的停起售状态设置 2.套餐的停起售状态设置 3.动态sql中的 useGeneratedKeys 与 keyProperty 两个参数 一. 菜品的停起售状态设置 ​ 在菜品的停售中…

React之旅-05 List Key

每个React的初学者&#xff0c;在调试程序时&#xff0c;都会遇到这样的警告&#xff1a;Warning: Each child in a list should have a unique "key" prop. 如下面的代码&#xff1a; const list [Learn React, Learn GraphQL];const ListWithoutKey () > (&l…

[特殊字符] 人工智能技术全景:从基础理论到前沿应用的深度解析

&#x1f680; 人工智能技术全景&#xff1a;从基础理论到前沿应用的深度解析 在这个AI驱动的时代&#xff0c;理解人工智能的核心技术和应用场景已成为技术人员的必备技能。本文将带你深入探索AI的发展脉络、核心技术差异以及在各行业的创新应用。 文章目录&#x1f680; 人工…

Go语言教程-环境搭建

前言 Go&#xff08;又称 Golang&#xff09;是由 Google 开发的一种 开源、静态类型、编译型 编程语言&#xff0c;于 2009 年正式发布。它旨在解决现代软件开发中的高并发、高性能和可维护性问题&#xff0c;尤其适合 云计算、微服务、分布式系统 等领域。 Go 语言国际官网…

windows指定某node及npm版本下载

下载并安装 nvm-windowshttps://github.com/coreybutler/nvm-windows/releases&#xff08;选择 nvm-setup.zip&#xff09;。打开命令提示符&#xff08;管理员权限&#xff09;&#xff0c;安装 Node.js v16.15.0&#xff1a; nvm install 16.15.0 nvm use 16.15.0 验证node版…

每天一个前端小知识 Day 28 - Web Workers / 多线程模型在前端中的应用实践

Web Workers / 多线程模型在前端中的应用实践&#x1f9e0; 一、为什么前端需要多线程&#xff1f; 单线程 JS 的瓶颈&#xff1a;浏览器主线程不仅负责执行 JS&#xff0c;还要负责&#xff1a; UI 渲染&#xff08;DOM/CSS&#xff09;用户事件处理&#xff08;点击、输入&am…

python:ImportError: cannot import name ‘ParameterSource‘ from ‘click.core‘

浏览器访问网站抛错&#xff1a;ImportError: cannot import name ParameterSource from click.core (E:\environment\python\Lib\site-packages\click\core.py)问题分析&#xff1a;1. click 版本问题ParameterSource 可能是在某个特定版本的 click 库中引入的&#xff0c;而你…

flink 去重

LOCALTIMESTAMP as time_stamp ts as case when time is null then CURRENT_TIMESTAMP else TO_TIMESTAMP_LTZ(time, 0) end , watermark for ts as ts - interval ‘60’ second PARTITION BY 的都有回撤流 group by 的没有回撤流 因为算的是指标 开窗又慢 SELECT * FROM (…

【音视频】TS协议解析

参考博客&#xff1a;https://blog.csdn.net/rell336/article/details/38109621?utm_mediumdistribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_sourcedistribute.pc_relevant_t0.none-task-blog-BlogCommendFromMac…

uniapp 日期组件可选择年月

month-picker 月份选择器组件 组件介绍 month-picker 是一个用于选择年月的自定义组件&#xff0c;基于 uni-app 开发&#xff0c;提供了简洁的月份选择功能。 解决弹框底部出现底部页面区域 safe-area属性设为true时&#xff0c;即可解决这个问题效果如图功能特点 支持选择年份…

从真人到数字分身:3D人脸扫描设备在高校数字人建模教学中的应用

在影视、动漫、游戏等数字创意产业蓬勃发展的当下&#xff0c;超写实虚拟数字人凭借其高度逼真的形象&#xff0c;成为行业关注的焦点。无论是影视特效中栩栩如生的角色&#xff0c;还是游戏里精致的NPC&#xff0c;超写实虚拟数字人的制作都离不开先进的技术支撑。而3D人脸扫描…

你以为大数据只是存?其实真正的“宝藏”藏在这招里——数据挖掘!

你以为大数据只是存&#xff1f;其实真正的“宝藏”藏在这招里——数据挖掘&#xff01; 曾经我也天真地以为&#xff0c;搞大数据就是会写几个SQL、部署个Hadoop集群&#xff0c;结果真到项目现场&#xff0c;甲方爸爸一句&#xff1a;“给我挖掘一下用户的购买意图”&#xf…

LeetCode经典题解:128、最长连续序列

“最长连续序列”是一道极具代表性的数组处理问题&#xff0c; 本文将带你从直观思路出发&#xff0c;逐步推导出最优解法&#xff0c;并通过场景化记忆技巧掌握核心逻辑。 一、题目描述 题目&#xff1a;给定一个未排序的整数数组 nums&#xff0c;找出数字连续的最长序列&…

电力分析仪的“双语对话”:CCLinkIE与Modbus TCP的无缝连接

在工业自动化领域&#xff0c;协议兼容性问题如同“方言壁垒”&#xff0c;让不同品牌、不同系统的设备难以高效协同。对于电力分析仪这类关键设备而言&#xff0c;如何打破CCLinkIE与Modbus TCP协议的“语言障碍”&#xff0c;已成为工程师优化系统集成的核心课题。 为何需要协…

暑假复习篇之文本编译器

一、知识点补充【在此次示例代码上显示的关键用法】知识点1、JMenuBar&#xff1a;菜单栏的容器&#xff0c;通常添加到JFrame的顶部。关键用法&#xff1a;add&#xff1a; 添加菜单到菜单栏2、JMenu&#xff1a;菜单条目&#xff08;“文件” “编辑” 等&#xff09;&#x…