深入解析 C++ 字符串处理:提取和分割的多种方法
在 C++ 编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时。本文将详细探讨如何使用 C++ 标准库中的工具(如 std::istringstream 和 std::string 的成员函数)来提取和分割字符串,并分析不同方法的适用场景和优缺点。我们将通过多个示例代码逐步讲解,帮助读者掌握字符串处理的技巧。
1. 字符串提取的基本方法
1.1 使用 std::istringstream 和 >> 操作符
std::istringstream 是 C++ 标准库中的一个类,它将字符串作为输入流来处理。通过 >> 操作符,我们可以从流中提取以空格分隔的单词或数字。
示例代码
#include <iostream>
#include <sstream>
#include <string>int main() {std::string s = "id13 id1 id6 id0 id8 id6 id0";std::istringstream iss(s);std::string token;while (iss >> token) {std::cout << token << std::endl;}return 0;
}
输出
id13
id1
id6
id0
id8
id6
id0
分析
-
iss >> token会按空格分隔字符串,逐个提取单词。 -
这种方法适用于字符串中的单词是用空格分隔的简单场景。
1.2 提取 id 后面的数字
如果需要从类似 "id13 id1 id6" 的字符串中提取 id 后面的数字,可以使用 std::string::substr 方法。
示例代码
#include <iostream>
#include <sstream>
#include <string>
#include <vector>int main() {std::string s = "id13 id1 id6 id0 id8 id6 id0";std::istringstream iss(s);std::string token;std::vector<int> ids;while (iss >> token) {if (token.substr(0, 2) == "id") {int id = std::stoi(token.substr(2));ids.push_back(id);}}for (int id : ids) {std::cout << id << std::endl;}return 0;
}
输出
13
1
6
0
8
6
0
分析
-
token.substr(2)从token的第 2 个字符开始提取子串,跳过"id"。 -
无论
id后面的数字是一位数、两位数还是三位数,substr(2)都能正确提取。 -
这种方法简洁高效,适用于提取固定前缀后的数字。
2. 处理复杂分隔符
2.1 使用 std::getline 自定义分隔符
如果字符串的分隔符不是空格(例如逗号 , 或分号 ;),可以使用 std::getline 并指定分隔符。
示例代码
#include <iostream>
#include <sstream>
#include <string>
#include <vector>int main() {std::string s = "id13,id1,id6,id0,id8,id6,id0";std::istringstream iss(s);std::string token;std::vector<int> ids;while (std::getline(iss, token, ',')) {if (token.substr(0, 2) == "id") {int id = std::stoi(token.substr(2));ids.push_back(id);}}for (int id : ids) {std::cout << id << std::endl;}return 0;
}
输出
13
1
6
0
8
6
0
分析
-
std::getline(iss, token, ',')会按逗号分隔字符串,逐个提取单词。 -
这种方法适用于处理自定义分隔符的场景。
2.2 处理多行输入
如果输入是多行的,std::getline 也可以按行提取内容。
示例代码
#include <iostream>
#include <sstream>
#include <string>int main() {std::string s = "id13 id1 id6\nid0 id8 id6\nid0";std::istringstream iss(s);std::string line;while (std::getline(iss, line)) {std::istringstream lineStream(line);std::string token;while (lineStream >> token) {std::cout << token << std::endl;}}return 0;
}
输出
id13
id1
id6
id0
id8
id6
id0
分析
-
外层
std::getline按行提取内容。 -
内层
lineStream >> token按空格分隔每行的单词。 -
这种方法适用于处理多行输入的场景。
3. 高级字符串处理技巧
3.1 使用正则表达式
C++11 引入了 <regex> 库,支持正则表达式匹配,可以更灵活地处理字符串。
示例代码
#include <iostream>
#include <regex>
#include <string>
#include <vector>int main() {std::string s = "id13 id1 id6 id0 id8 id6 id0";std::regex pattern(R"(id(\d+))");std::smatch matches;std::vector<int> ids;auto words_begin = std::sregex_iterator(s.begin(), s.end(), pattern);auto words_end = std::sregex_iterator();for (std::sregex_iterator i = words_begin; i != words_end; ++i) {std::smatch match = *i;int id = std::stoi(match.str(1));ids.push_back(id);}for (int id : ids) {std::cout << id << std::endl;}return 0;
}
输出
13
1
6
0
8
6
0
分析
-
使用正则表达式
R"(id(\d+))"匹配id后面的数字。 -
这种方法功能强大,但语法较复杂,适合处理复杂的字符串匹配任务。
3.2 性能优化
对于大规模数据处理,性能可能成为瓶颈。可以通过以下方法优化:
-
避免频繁创建和销毁
std::istringstream对象。 -
使用
std::string_view(C++17)减少字符串拷贝。
示例代码
#include <iostream>
#include <sstream>
#include <string>
#include <vector>int main() {std::string s = "id13 id1 id6 id0 id8 id6 id0";std::istringstream iss(s);std::string token;std::vector<int> ids;ids.reserve(10); // 预分配空间while (iss >> token) {if (token.substr(0, 2) == "id") {int id = std::stoi(token.substr(2));ids.push_back(id);}}for (int id : ids) {std::cout << id << std::endl;}return 0;
}
分析
-
预分配
ids的空间可以减少动态内存分配的开销。 -
使用
std::string_view可以避免不必要的字符串拷贝。
4. 总结
本文详细介绍了 C++ 中字符串提取和分割的多种方法,包括:
-
使用
std::istringstream和>>操作符按空格分隔字符串。 -
使用
std::getline处理自定义分隔符和多行输入。 -
使用正则表达式处理复杂的字符串匹配任务。
-
通过性能优化技巧提高代码效率。
每种方法都有其适用的场景和优缺点,开发者可以根据具体需求选择合适的方法。掌握这些技巧后,你将能够高效地处理各种字符串任务,提升代码的可读性和性能。
通过本文的学习,希望读者能够深入理解 C++ 字符串处理的精髓,并在实际项目中灵活运用这些方法。
相关文章:
深入解析 C++ 字符串处理:提取和分割的多种方法
在 C 编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时。本文将详细探讨如何使用 C 标准库中的工具(如 std::istringstream 和 std::string 的成员函数)来提取和分割字符串,并分析不同方法的适…...
计算机组成原理——存储系统(一)
在人生的道路上,成功与失败交织成一幅丰富多彩的画卷。不论我们是面对胜利的喜悦,还是遭遇失败的痛苦,都不能放弃对梦想的追求。正是在这种追求中,我们不断地超越自我,不断地突破自己的极限。只有勇往直前,…...
Jenkins未在第一次登录后设置用户名,第二次登录不进去怎么办?
Jenkins在第一次进行登录的时候,只需要输入Jenkins\secrets\initialAdminPassword中的密码,登录成功后,本次我们没有修改密码,就会导致后面第二次登录,Jenkins需要进行用户名和密码的验证,但是我们根本就没…...
论文和代码解读:RF-Inversion 图像/视频编辑技术
Diffusion Models专栏文章汇总:入门与实战 前言:Rectified Flow的反演和DDIM这些不太一样,上一篇博客中介绍了腾讯提出的一种方法《基于Rectified Flow FLUX的图像编辑方法 RF-Solver》,主要就是用泰勒展开和一阶导数近似来分解反演公式。这篇博客介绍谷歌提出的方法RF-Inv…...
大模型培训讲师老师叶梓分享:DeepSeek多模态大模型janus初探
以下视频内容为叶梓分享DeepSeek多模态大模型janus的部署,并验证其实际效果,包括图生文和文生图两部分。 叶梓老师人工智能培训分享DeepSeek多模态大模型janus初探 DeepSeek 的多模态大模型 Janus 是一款强大的 AI 模型,专注于图像和文本的多…...
2025最新源支付V7全套开源版+Mac云端+五合一云端
2025最新源支付V7全套开源版Mac云端五合一云端 官方1999元, 最新非网上那种功能不全带BUG开源版,可以自己增加授权或二开 拥有卓越的性能和丰富的功能。它采用全新轻量化的界面UI,让您能更方便快捷地解决知识付费和运营赞助的难题 它基于…...
稀疏混合专家架构语言模型(MoE)
注:本文为 “稀疏混合专家架构语言模型(MoE)” 相关文章合辑。 手把手教你,从零开始实现一个稀疏混合专家架构语言模型(MoE) 机器之心 2024年02月11日 12:21 河南 选自huggingface 机器之心编译 机器之心…...
比较热门的嵌入式项目
嵌入式系统在现代科技中应用广泛,以下是一些当前比较热门的嵌入式项目方向及其应用场景: 1. 物联网(IoT) 智能家居:智能灯光、温控器、安防系统。环境监测:空气质量、温湿度、土壤湿度传感器。工业物联网&…...
牛客网 除2!(详解)c++
题目链接:除2! 1.题目解析 1:想让数组所有数之和尽可能小,肯定有个想法,就是我每次选数组中偶数的时候,我必定挑一个最大的,因为我挑一个最大的出来,把它变成一半,这个时…...
被裁与人生的意义--春节随想
还有两个月就要被迫离开工作了十多年的公司了,不过有幸安安稳稳的过了一个春节,很知足! 我是最后一批要离开的,一百多号同事都没“活到”蛇年。看着一批批仁人志士被“秋后斩首”,马上轮到我们十来个,个中滋味很难言清…...
ASP.NET Core 中间件
目录 一、常见的内置中间件 二、自定义中间件 三、中间件的执行顺序 四、其他自动逸中间件案例 1. 身份验证中间件 2、跨域中间件(CORS) ASP.NET Core 中,中间件(Middleware)是处理 HTTP 请求和响应的组件链。你…...
Pyecharts之图表样式深度定制
在数据可视化的世界里,图表的样式定制对于提升数据展示效果和用户体验至关重要。Pyecharts 提供了丰富的样式定制功能,能让我们创建出独具特色的可视化作品。本篇将深入探讨如何使用 Pyecharts 为图表添加线性渐变色、径向渐变色,以及如何添加…...
git笔记-简单入门
git笔记 git是一个分布式版本控制系统,它的优点有哪些呢?分为以下几个部分 与集中式的版本控制系统比起来,不用担心单点故障问题,只需要互相同步一下进度即可。支持离线编辑,每一个人都有一个完整的版本库。跨平台支持…...
Joplin 插件在Vscode中无法显示图片
1.问题 在vscode里面装好joplin插件之后,无法显示图片内容。 粘贴的图片可以再vscode中显示,无法再joplin客户端显示 2.解决方法 这种情况是因为和vscode自带的MD编辑器的预览模式有冲突,或者没用通过专用方式上传图片。 方法一ÿ…...
python学opencv|读取图像(四十七)使用cv2.bitwise_not()函数实现图像按位取反运算
【0】基础定义 按位与运算:两个等长度二进制数上下对齐,全1取1,其余取0。按位或运算:两个等长度二进制数上下对齐,有1取1,其余取0。 按位取反运算:一个二进制数,0变1,1变0。 【1】…...
pandas分组
分组 分组的关键要素是: 分组依据、数据来源、操作及其返回结果。 df.groupby(分组依据)[数据来源].使用操作对学生按照性别统计身高中位数。 print(df.groupby(Gender)[Height].median())上面是一维度进行分组,如果要根据多个维度分组,则…...
爬虫基础(三)Session和Cookie讲解
目录 一、前备知识点 (1)静态网页 (2)动态网页 (3)无状态HTTP 二、Session和Cookie 三、Session 四、Cookie (1)维持过程 (2)结构 正式开始说 Sessi…...
【Super Tilemap Editor使用详解】(十三):快捷键指南(Keyboard Shortcuts)
在使用 Super Tilemap Editor 进行图块地图编辑时,键盘快捷键可以显著提高工作效率。本文将详细介绍常用的快捷键及其功能,帮助你更快地完成图块绘制、翻转、旋转以及工具切换等操作。 一、快捷键文件位置 所有键盘快捷键的定义可以在以下路径找到&…...
【Leetcode 每日一题】119. 杨辉三角 II
问题背景 给定一个非负索引 r o w I n d e x rowIndex rowIndex,返回「杨辉三角」的第 r o w I n d e x rowIndex rowIndex 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 数据约束 0 ≤ r o w I n d e x ≤ 33 0 \le rowIndex \le 33 …...
简单看看会议系统2(时延分析)(TODO)
(TODO) eBPF (extended Berkeley Packet Filter) 可以用来跟踪和分析树莓派 5 或其他 Linux 系统中的各种活动,包括拍摄和数据传输过程的性能分析。eBPF 是一个强大的内核级工具,可以在不修改内核源码的情况下,动态地跟…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)
cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...
leetcode73-矩阵置零
leetcode 73 思路 记录 0 元素的位置:遍历整个矩阵,找出所有值为 0 的元素,并将它们的坐标记录在数组zeroPosition中置零操作:遍历记录的所有 0 元素位置,将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...
