C++之std::stringstream详解

C++之std::stringstream详解

目录

1.简介

2.核心功能与示例

2.1.类型转换(最常用)

2.2.字符串拼接

2.3.字符串分割

3.进阶用法

4.注意事项

5.总结


1.简介

        std::stringstream 是 C++ 标准库 <sstream> 头文件提供的字符串流类,核心作用是在字符串基本数据类型之间做转换,以及灵活地拼接 / 分割字符串。它属于内存流(而非文件流),所有操作都在内存中完成,效率高且使用灵活。

        头文件:

#include <sstream> // 核心:字符串流 #include <iostream> // 控制台输出(辅助) #include <string> // 处理字符串(辅助) using namespace std; // 简化代码,实际项目可按需省略

<sstream> 提供三个核心类(均继承自 std::iostream):

类名 核心功能 类比 std::istringstream 只读字符串流(输入流) 类似 ifstream std::ostringstream 只写字符串流(输出流) 类似 ofstream std::stringstream 读写字符串流(双向流) 类似 fstream

2.核心功能与示例

2.1.类型转换(最常用)

stringstream 是 C++ 中灵活的类型转换工具,可实现任意基本类型(int/float/double 等)与字符串的互转,比 atoi/atof 或 C++11 的 std::to_string 更通用(支持多类型混合转换)。

1.数字 → 字符串

// 单个数字转字符串 int num = 123; ostringstream oss; oss << num; // 像输出到控制台一样写入字符串流 string str_num = oss.str(); // 获取流中的字符串 cout << "int转string:" << str_num << endl; // 输出:123 // 多类型混合转字符串 double pi = 3.14159; bool flag = true; ostringstream oss2; oss2 << "π = " << pi << ",是否有效:" << boolalpha << flag; string str_mix = oss2.str(); cout << str_mix << endl; // 输出:π = 3.14159,是否有效:true

2.字符串 → 数字

// 字符串转单个数字 string str = "456.789"; istringstream iss(str); double d; iss >> d; // 像从控制台读取一样解析字符串 if (iss.fail()) { // 检查转换是否失败(如字符串非数字) cerr << "转换失败!" << endl; } else { cout << "string转double:" << d << endl; // 输出:456.789 } // 字符串转多个数字(按空格分割) string str_multi = "10 20.5 300"; istringstream iss2(str_multi); int a; double b; int c; iss2 >> a >> b >> c; cout << a << " " << b << " " << c << endl; // 输出:10 20.5 300

2.2.字符串拼接

ostringstream 比直接用 + 拼接字符串更高效(减少临时字符串创建),尤其适合大量拼接场景。

// 低效方式:多次+拼接(产生临时对象) string s1 = "姓名:" + "张三" + ",年龄:" + to_string(20); // 高效方式:ostringstream拼接 ostringstream oss; oss << "姓名:" << "张三" << ",年龄:" << 20 << ",分数:" << 95.5; string s2 = oss.str(); cout << s2 << endl; // 输出:姓名:张三,年龄:20,分数:95.5

2.3.字符串分割

istringstream 配合 >> 或 getline() 可轻松分割字符串(按空格、逗号、冒号等分隔符)。

1.按空格 / 制表符分割(默认)

string str = "apple banana orange grape"; istringstream iss(str); string word; // >> 自动跳过空格/制表符/换行符,读取到下一个分隔符为止 while (iss >> word) { cout << word << endl; } // 输出: // apple // banana // orange // grape

2.按自定义分隔符分割(如逗号、冒号)

需配合 getline() 指定分隔符:

string str = "1,2,3,4,5"; istringstream iss(str); string token; // getline(流, 接收字符串, 分隔符) while (getline(iss, token, ',')) { cout << token << endl; } // 输出: // 1 // 2 // 3 // 4 // 5 // 按冒号分割示例 string str2 = "name:张三:age:20:score:95.5"; istringstream iss2(str2); string t; while (getline(iss2, t, ':')) { cout << t << endl; }

3.进阶用法

1.清空 / 重置 stringstream

stringstream 的清空需注意两个关键点:

  • clear():仅重置流的状态标志(如 eof/fail 标志),不清空内部字符串;
  • str(""):清空内部存储的字符串内容;
  • 如需复用流,需同时调用 clear() + str("")
stringstream ss; ss << "test 123"; cout << "初始内容:" << ss.str() << endl; // 输出:test 123 // 错误:仅clear(),内容仍在 ss.clear(); cout << "仅clear()后:" << ss.str() << endl; // 输出:test 123 // 正确:清空内容 + 重置状态 ss.str(""); // 清空内容 ss.clear(); // 重置状态(避免之前的状态影响后续操作) ss << "new content"; cout << "重置后:" << ss.str() << endl; // 输出:new content

2.获取 / 设置流的内容

  • str():无参数 → 获取流中的字符串;
  • str(const string& s):有参数 → 设置流的初始内容。
stringstream ss; ss.str("初始内容"); // 设置初始内容 cout << ss.str() << endl; // 输出:初始内容 ss << " + 追加内容"; cout << ss.str() << endl; // 输出:初始内容 + 追加内容

4.注意事项

  1. 清空误区:切勿仅用 clear() 清空内容,必须配合 str("")
  2. 性能优势:拼接大量字符串时,ostringstream 远优于 string::operator+(减少内存拷贝);
  3. 错误处理:类型转换 / 分割时,需检查 fail()/good() 状态,避免无效转换(如字符串 "abc" 转 int);
  4. 线程安全stringstream 非线程安全,多线程操作需加锁;
  5. 内存占用stringstream 会缓存数据,大量数据处理后及时清空或析构,避免内存泄漏;
  6. bool 类型输出:默认输出 1/0,需用 boolalpha 操纵符输出 true/false
ostringstream oss; oss << boolalpha << true; // 输出 true oss << noboolalpha << true; // 输出 1(恢复默认)

5.总结

std::stringstream 是 C++ 处理字符串的 “瑞士军刀”,核心价值:

  • 灵活的类型转换(数字↔字符串);
  • 高效的字符串拼接
  • 便捷的字符串分割
  • 所有操作在内存中完成,无 IO 开销,性能优异。

实际开发中,优先用 istringstream 处理 “读 / 解析”、ostringstream 处理 “写 / 拼接”,stringstream 仅在需要双向操作时使用(略占内存)。

Read more

Rust微服务架构实战——gRPC通信、服务发现与容器编排

Rust微服务架构实战——gRPC通信、服务发现与容器编排

第12篇:Rust微服务架构实战——gRPC通信、服务发现与容器编排 一、学习目标与重点 1.1 学习目标 1. 理解微服务架构:深入学习微服务的核心概念、优缺点、架构模式,掌握微服务与单体架构的区别 2. 掌握gRPC通信:熟练使用Tonic(Rust的gRPC实现)定义.proto文件、生成服务端和客户端代码,实现同步/异步通信 3. 实现服务发现与负载均衡:使用Consul或etcd实现服务注册与发现,使用Ribbon或Nginx实现负载均衡 4. 容器编排与部署:学习Docker Swarm或Kubernetes的核心概念,使用Docker Compose或Kubernetes YAML文件部署微服务 5. 实战微服务开发:结合真实场景编写用户管理、订单管理、支付管理三个微服务,实现gRPC通信、服务发现、负载均衡 6. 监控与运维:使用Prometheus+Grafana监控微服务,使用ELK Stack收集和分析日志 1.

By Ne0inhk
Flask工厂模式与蓝图设计:构建可扩展大型应用的架构之道

Flask工厂模式与蓝图设计:构建可扩展大型应用的架构之道

目录 📖 摘要 🏗️ 第一章:为什么需要工厂模式? 1.1 从单体应用到模块化架构 1.2 工厂模式的诞生 1.3 性能提升数据 🔧 第二章:Flask应用工厂深度解析 2.1 基础工厂实现 2.2 配置管理 2.3 扩展初始化顺序 🧩 第三章:蓝图模块化架构 3.1 蓝图基础 3.2 企业级蓝图结构 3.3 蓝图间通信 🚀 第四章:完整电商平台实战 4.1 项目结构 4.2 应用工厂完整实现 4.3 数据模型设计 4.4 测试策略 🚀 第五章:

By Ne0inhk
SkyWalking - Kafka _ RabbitMQ 消息链路追踪支持

SkyWalking - Kafka _ RabbitMQ 消息链路追踪支持

👋 大家好,欢迎来到我的技术博客! 📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。 🎯 本文将围绕SkyWalking这个话题展开,希望能为你带来一些启发或实用的参考。 🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获! 文章目录 * SkyWalking - Kafka / RabbitMQ 消息链路追踪支持 🚀 * 为什么需要消息链路追踪?🤔 * SkyWalking 核心概念回顾 🔍 * Kafka 链路追踪支持 🐘 * 1. 自动探针(推荐)✅ * 前提条件 * 工作原理 * Java 代码示例(无需修改业务代码!) * 验证追踪效果 * 2. 手动埋点(高级场景)🛠️ * 添加依赖 * 手动注入上下文(Producer) * 手动提取上下文(Consumer) * RabbitMQ 链路追踪支持 🐇 * 工作原理 * Java 代码

By Ne0inhk

前端知识点梳理,前端面试复习

一:从输入 URL 到页面渲染是一个经典的综合性考题 1.URL 的标准组成部分 一个完整的 URL 结构如下: scheme://host:port/path?query#fragment URI 用字符串标识某一互联网资源,而URL 表示资源的地点(互 联网上所处的位置)。可见URL是URI 的子集。 URI 和 URL 的区别? * URI (Uniform Resource Identifier) 是统一资源标识符,是一个大概念。 * URL (Uniform Resource Locator) 是统一资源定位符,它不仅标识资源,还提供了找到资源的方式(比如协议)。可以理解为 URL 是 URI 的子集。 为什么 URL 中有些字符会被转义(

By Ne0inhk