C++ 字符串流化 stringstream

   

目录

原理

1. std::stringstream 概述

2. 内部机制

3. 工作原理

写入数据

读取数据

4. 主要操作

妙用

1. 将数据格式化为字符串

2. 从字符串解析数据

3. 字符串到数值转换、 数值到字符串转换

4. 合并字符串

5. 动态生成 SQL 查询

6. 日志系统

7. 基于模板生成代码

8. URL 解析

9. 生成 HTML

10. 动态命令行生成

总结

附:自定义 MyStringStream 类


     

        C++ 中的字符串流化(string stream)是通过标准库提供的 std::stringstream 实现的。std::stringstreamstd::iostream 的子类,它允许我们将字符串作为流进行读写操作。下面我将解释字符串流化的原理,包括其内部机制和工作方式。

原理

1. std::stringstream 概述

  std::stringstream 位于 <sstream> 头文件中,是 std::basic_stringstream<char> 的类型定义。它是一个模板类,继承自 std::iostream,可以同时进行输入和输出操作。

2. 内部机制

  std::stringstream 的核心是使用一个 std::stringbuf 对象,该对象是 std::basic_stringbuf<char> 的实例。std::stringbuf 提供了将字符串作为流缓冲区的能力。

  • std::stringbuf:该类继承自 std::basic_streambuf<char>,用于管理内部字符串缓冲区。它提供了读写字符串的接口。
  • std::stringstream:组合了 std::istreamstd::ostream 的功能,通过 std::stringbuf 实现对字符串的读写操作。

3. 工作原理

  std::stringstream 使用内部的 std::stringbuf 对象来存储和管理字符串数据。std::stringbuf 维护一个内部缓冲区(即 std::string 对象),可以通过流操作将数据写入或从中读取。

写入数据
  • 当我们向 std::stringstream 写入数据时,数据被插入到内部缓冲区中。
  • 流操作符(<<)重载实现了对各种数据类型的格式化写入。
std::stringstream ss;
ss << 123 << " " << 45.67;  // 将整数和浮点数写入字符串流
读取数据
  • 当我们从 std::stringstream 读取数据时,数据从内部缓冲区中提取。
  • 流操作符(>>)重载实现了对各种数据类型的解析读取。
std::stringstream ss("123 45.67");
int a;
double b;
ss >> a >> b;  // 从字符串流中读取整数和浮点数

4. 主要操作

  • 插入数据:使用 << 操作符将数据插入到字符串流中。
  • 提取数据:使用 >> 操作符从字符串流中提取数据。
  • 获取字符串:使用 str() 方法获取内部缓冲区的字符串表示。
  • 设置字符串:使用 str(const std::string& s) 方法设置内部缓冲区的内容。
  • 清空流:使用 str("")clear() 清空流内容和状态。
#include <iostream>
#include <sstream>
#include <string>

int main() {
    // 创建一个字符串流对象
    std::stringstream ss;

    // 写入数据到字符串流
    int num = 42;
    double pi = 3.14159;
    ss << "Number: " << num << ", Pi: " << pi;

    // 获取字符串流的内容
    std::string str = ss.str();
    std::cout << "Stream content: " << str << std::endl;

    // 清空字符串流
    ss.str("");
    ss.clear();

    // 写入新的数据到字符串流
    std::string data = "123 45.67";
    ss.str(data);

    // 从字符串流读取数据
    int a;
    double b;
    ss >> a >> b;
    std::cout << "Extracted values: a = " << a << ", b = " << b << std::endl;

    return 0;
}

妙用

1. 将数据格式化为字符串

        使用 std::stringstream 可以将各种类型的数据格式化为字符串。

#include <iostream>
#include <sstream>
#include <string>

int main() {
    std::stringstream ss;
    int n = 42;
    double pi = 3.14159;

    // 向字符串流中插入数据
    ss << "The value of n is " << n << " and the value of pi is " << pi;

    // 将字符串流转换为字符串
    std::string result = ss.str();
    std::cout << result << std::endl;

    return 0;
}

2. 从字符串解析数据

        使用 std::stringstream 可以从字符串中解析出不同类型的数据。

#include <iostream>
#include <sstream>
#include <string>

int main() {
    std::string data = "42 3.14159";
    std::stringstream ss(data);

    int n;
    double pi;

    // 从字符串流中提取数据
    ss >> n >> pi;

    std::cout << "The value of n is " << n << " and the value of pi is " << pi << std::endl;

    return 0;
}

3. 字符串到数值转换、 数值到字符串转换

#include <iostream>
#include <sstream>
#include <string>

int main() {
    std::string numberStr = "12345";
    int number;
    std::stringstream ss(numberStr);
    ss >> number;

    if (ss.fail()) {
        std::cout << "Conversion failed!" << std::endl;
    } else {
        std::cout << "Converted number: " << number << std::endl;
    }

    return 0;
}
#include <iostream>
#include <sstream>
#include <string>

int main() {
    int number = 12345;
    std::stringstream ss;
    ss << number;

    std::string numberStr = ss.str();
    std::cout << "Converted string: " << numberStr << std::endl;

    return 0;
}

4. 合并字符串

  std::stringstream 可以用于高效地拼接多个字符串。

#include <iostream>
#include <sstream>
#include <string>

int main() {
    std::string firstName = "John";
    std::string lastName = "Doe";
    int age = 30;

    std::stringstream ss;
    ss << "Name: " << firstName << " " << lastName << ", Age: " << age;

    std::string result = ss.str();
    std::cout << result << std::endl;

    return 0;
}

5. 动态生成 SQL 查询

  std::stringstream 可以用于动态生成复杂的 SQL 查询语句。

#include <iostream>
#include <sstream>
#include <string>

std::string generateSQLQuery(const std::string& tableName, const std::string& column, int value) {
    std::stringstream ss;
    ss << "SELECT * FROM " << tableName << " WHERE " << column << " = " << value;
    return ss.str();
}

int main() {
    std::string query = generateSQLQuery("users", "age", 25);
    std::cout << "Generated SQL Query: " << query << std::endl;

    return 0;
}

6. 日志系统

#include <iostream>
#include <sstream>
#include <string>
#include <fstream>

class Logger {
public:
    void log(const std::string& message) {
        std::stringstream ss;
        ss << "[INFO] " << message;
        writeLog(ss.str());
    }

    void logError(const std::string& message) {
        std::stringstream ss;
        ss << "[ERROR] " << message;
        writeLog(ss.str());
    }

private:
    void writeLog(const std::string& logEntry) {
        std::ofstream logFile("log.txt", std::ios_base::app);
        logFile << logEntry << std::endl;
    }
};

int main() {
    Logger logger;
    logger.log("This is an information message.");
    logger.logError("This is an error message.");

    return 0;
}

7. 基于模板生成代码

  std::stringstream 可以用于代码生成工具,通过模板生成不同的代码片段。

#include <iostream>
#include <sstream>
#include <string>

std::string generateFunction(const std::string& returnType, const std::string& functionName, const std::string& params) {
    std::stringstream ss;
    ss << returnType << " " << functionName << "(" << params << ") {\n";
    ss << "    // function body\n";
    ss << "}\n";
    return ss.str();
}

int main() {
    std::string code = generateFunction("int", "add", "int a, int b");
    std::cout << "Generated Function Code:\n" << code << std::endl;

    return 0;
}

8. URL 解析

#include <iostream>
#include <sstream>
#include <string>
#include <map>

std::map<std::string, std::string> parseURLParameters(const std::string& url) {
    std::map<std::string, std::string> params;
    std::string::size_type pos = url.find('?');
    if (pos == std::string::npos) {
        return params;
    }

    std::string query = url.substr(pos + 1);
    std::stringstream ss(query);
    std::string param;

    while (std::getline(ss, param, '&')) {
        std::string::size_type eqPos = param.find('=');
        if (eqPos != std::string::npos) {
            std::string key = param.substr(0, eqPos);
            std::string value = param.substr(eqPos + 1);
            params[key] = value;
        }
    }

    return params;
}

int main() {
    std::string url = "http://example.com/page?param1=value1&param2=value2&param3=value3";
    std::map<std::string, std::string> params = parseURLParameters(url);

    std::cout << "Parsed URL Parameters:" << std::endl;
    for (const auto& param : params) {
        std::cout << param.first << ": " << param.second << std::endl;
    }

    return 0;
}

9. 生成 HTML

#include <iostream>
#include <sstream>
#include <string>
#include <vector>

std::string generateHTML(const std::vector<std::string>& items) {
    std::stringstream ss;
    ss << "<ul>\n";
    for (const auto& item : items) {
        ss << "  <li>" << item << "</li>\n";
    }
    ss << "</ul>";
    return ss.str();
}

int main() {
    std::vector<std::string> items = {"Item 1", "Item 2", "Item 3"};
    std::string html = generateHTML(items);

    std::cout << "Generated HTML:\n" << html << std::endl;

    return 0;
}

10. 动态命令行生成

#include <iostream>
#include <sstream>
#include <string>

std::string generateCommand(const std::string& command, const std::vector<std::string>& args) {
    std::stringstream ss;
    ss << command;
    for (const auto& arg : args) {
        ss << " " << arg;
    }
    return ss.str();
}

int main() {
    std::vector<std::string> args = {"-o", "output.txt", "-i", "input.txt", "--verbose"};
    std::string command = generateCommand("my_program", args);

    std::cout << "Generated Command: " << command << std::endl;

    return 0;
}

总结

        可以看到 std::stringstream 在各种实际编程任务中都有广泛的应用。不论是格式化输出、数据解析、生成动态内容,还是处理多行文本、生成命令行字符串等,std::stringstream 都提供了灵活且强大的解决方案。这些示例展示了 std::stringstream 的多种妙用,希望能帮助你更好地理解和应用这一强大的工具。

附:自定义 MyStringStream

#include <iostream>
#include <string>
#include <sstream>

class MyStringStream {
public:
    MyStringStream() {}

    // 写入数据到流
    template<typename T>
    MyStringStream& operator<<(const T& value) {
        buffer << value;
        return *this;
    }

    // 从流中读取数据
    template<typename T>
    MyStringStream& operator>>(T& value) {
        buffer >> value;
        return *this;
    }

    // 获取流的内容
    std::string str() const {
        return buffer.str();
    }

    // 设置流的内容
    void str(const std::string& s) {
        buffer.str(s);
    }

    // 清空流
    void clear() {
        buffer.str("");
        buffer.clear();
    }

private:
    std::stringstream buffer;
};

int main() {
    MyStringStream myStream;

    // 写入数据
    myStream << "Hello, " << "world! " << 123 << " " << 45.67;

    // 获取流内容
    std::string content = myStream.str();
    std::cout << "Stream content: " << content << std::endl;

    // 清空流
    myStream.clear();
    myStream << "New content: " << 789;
    content = myStream.str();
    std::cout << "Stream content after clear: " << content << std::endl;

    // 设置流内容
    myStream.str("100 200");
    int a, b;
    myStream >> a >> b;
    std::cout << "Extracted values: a = " << a << ", b = " << b << std::endl;

    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IIS在Windows上的搭建

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 目录 一 概念&#xff1a; 二网络…

Mozilla Firefox正在尝试集成ChatGPT等帮助用户总结或改写网页内容

Mozilla基金会开启了一项新计划&#xff1a;在接下来几个月里尝试在Firefox浏览器里集成 ChatGPT 等 AI 服务&#xff0c;帮助用户在网页上总结内容或者改写内容等。Firefox浏览器集成的 AI 服务包括但不限于 ChatGPT、Google Gemini、HuggingChat 等&#xff0c;当然这并不是把…

vue3import的插件全局引入

webpack 的引入 npm install -D unplugin-auto-import const AutoImport require(unplugin-auto-import/webpack).default;configureWebpack: {devtool: source-map,module: {rules: [{test: /\.mjs$/,include: /node_modules/,type: javascript/auto}],}, plugins: [Aut…

超详细的Pycharm使用虚拟环境搭建Django项目并创建新的虚拟环境教程

一、什么是虚拟环境&#xff1f; 通过软件虚拟出来的开发环境&#xff0c;不是真实存在的&#xff0c;一般在多套环境开发时会用到。 二、为什么要使用虚拟环境&#xff1f; 虚拟环境为不同的项目创建不同的开发环境&#xff0c;开发环境内所有使用的工具包互不影响。比如项…

安全工具 | BurpSuite安装使用(保姆级教程!)

Burp Suite下载,破解,代理web,代理模拟器 (一)为Burp Sutie下载运行执行脚本环境(Java) 1.Java官网下载地址&#xff1a;https://www.oracle.com/java/technologies/ 下载Java SE 17.0.8(LTS) 备注&#xff1a;1.2023版Burp Suite 完美的运行脚本的环境是Java17 2.Java8不支持…

matlab中函数meshgrid

(1) 二维网格 [X,Y] meshgrid(x,y) 基于向量 x 和 y 中包含的坐标返回二维网格坐标。X 是一个矩阵&#xff0c;每一行是 x 的一个副本&#xff1b;Y 也是一个矩阵&#xff0c;每一列是 y 的一个副本。坐标 X 和 Y 表示的网格有 length(y) 个行和 length(x) 个列。 x 1:3; y…

昇思25天学习打卡营第8天 | 保存与加载 使用静态图加速

保存与加载 在训练网络模型的过程中&#xff0c;实际上我们希望保存中间和最后的结果&#xff0c;用于微调&#xff08;fine-tune&#xff09;和后续的模型推理与部署&#xff0c;下面是介绍如何保存与加载模型。 先定义一个模型用&#xff1a; import numpy as np import m…

grpc学习golang版( 五、多proto文件示例)

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 第三章 proto文件数据类型 第四章 多服务示例 第五章 多proto文件示例 第六章 服务器流式传输 文章目录 一、前言二、定义proto文件2.1 公共proto文件2.2 语音唤醒proto文件2.3 人脸唤醒proto文件2.4 生成go代码2.…

最佳Google Chrome扩展和Mozilla Firefox扩展自动解决验证码

在这个信息爆炸的时代&#xff0c;我们每天都要处理大量的在线内容&#xff0c;验证码已成为不可避免的挑战。尽管它们旨在保护网站安全&#xff0c;但也常常成为我们获取信息的障碍。那么&#xff0c;有没有更简单的方法绕过这些验证码呢&#xff1f;答案是肯定的。通过使用一…

恭喜朱雀桥的越南薇妮她牌NFC山竹汁饮料,成为霸王茶姬奶茶主材

朱雀桥NFC山竹汁饮料&#xff1a;荣登霸王茶姬奶茶主材&#xff0c;非遗传承的天然之选 近日&#xff0c;据小编了解到&#xff1a;霸王茶姬欣喜地宣布&#xff0c;成功与朱雀桥达成合作越南薇妮她VINUT牌NFC山竹汁饮料。这款商超产品凭借其卓越的品质与独特的口感&#xff0c…

小项目——MySQL集训(学生成绩录入)

ddl语句 -- 创建学生信息表 CREATE TABLE students (student_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 学生ID,name VARCHAR(50) NOT NULL COMMENT 学生姓名,gender ENUM(男, 女) NOT NULL COMMENT 性别,class VARCHAR(50) NOT NULL COMMENT 班级,registration_date DATE CO…

【Termius】详细说明MacOS中的SSH的客户端利器Termius

希望文章能给到你启发和灵感~ 如果觉得有帮助的话,点赞+关注+收藏支持一下博主哦~ 阅读指南 开篇说明一、基础环境说明1.1 硬件环境1.2 软件环境二、软件的安装2.1 Termius界面介绍2.1.1 Hosts 主机列表2.1.2 SFTP 文件传输2.1.3 Port ForWarding 端口转发2.1.4 Snippets 片…

想要打造高效活跃的私域社群,这些技巧要知道

对一些企业来说“做社群等于做私域”。 在腾讯提到的私域转化场景中&#xff0c;社群与小程序、官方导购三者并列。 社群连接着品牌和群内用户。品牌通过圈住更多用户&#xff0c;来持续免费触达用户实现变现&#xff0c;用户则是从品牌方手中直接获取更多服务和优惠。那么&a…

LabVIEW中卡尔曼滤波的作用与意义

卡尔曼滤波&#xff08;Kalman Filter&#xff09;是一种在控制系统和信号处理领域广泛应用的递推滤波算法&#xff0c;能够在噪声环境下对动态系统的状态进行最优估计。其广泛应用于导航、目标跟踪、图像处理、经济预测等多个领域。本文将详细介绍卡尔曼滤波在LabVIEW中的作用…

手机越用越慢?试试这4个秘籍,让手机流畅如新

智能手机作为日常生活的得力助手&#xff0c;最初总是以惊人的速度和流畅性给我们留下深刻印象。 但你有没有发现&#xff0c;随着时间的推移&#xff0c;手机似乎开始变得不那么敏捷&#xff0c;甚至出现了反应迟缓和卡顿的情况&#xff1f; 别让这个问题困扰你,下面是四个关…

基于springboot、vue影院管理系统

设计技术&#xff1a; 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatisvue 工具&#xff1a;IDEA、Maven、Navicat 主要功能&#xff1a; 影城管理系统的主要使用者分为管理员和用户&#xff0c; 实现功能包括管理员&#xff1a; 首页…

从一道算法题开始,爱上Python编程

Python是一门简单易学、高效强大的编程语言&#xff0c;许多人因为它的便捷性和广泛应用而爱上编程。今天&#xff0c;我将通过一道有趣的算法题&#xff0c;带领大家一步步写出Python代码&#xff0c;并最终解决问题。希望通过这篇文章&#xff0c;能激发大家对Python编程的兴…

vue2+webpack 和 vite+vue3 配置获取环境变量(补充)

相关涉及知识点可看小编该文章&#xff1a; nginx: 部署前端项目的详细步骤&#xff08;vue项目build打包nginx部署&#xff09;_前端工程打包部署到nginx-CSDN博客 1.vue2webpack 我们通常会在项目中看到这么两个文件(没有则自己创建&#xff0c;文件名&#xff1a;.env.***) …

WITS核心价值观【创新】篇|从财务中来,到业务中去

「客尊」、「诚信」、「创新」 与「卓越」 是纬创软件的核心价值观。我们秉持诚信态度&#xff0c;致力于成为客户长期且值得信赖的合作伙伴。持续提升服务厚度&#xff0c;透过数字创新实践多市场的跨境交付&#xff0c;助客户保持市场领先地位。以追求卓越的不懈精神&#xf…

C++项目实践学习笔记---DLL

linux守护进程 守护进程或精灵进程&#xff08;Daemon&#xff09;&#xff1a;以后台服务方式运行的进程&#xff0c;它们不占用终端&#xff08;Shell&#xff09;&#xff0c;因此不会受终端输入或其他信号&#xff08;如中断信号&#xff09;的干扰守护进程有如下特点。 &…