C++ 字符串流化 stringstream

2024-06-21 07:52

本文主要是介绍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;
}

这篇关于C++ 字符串流化 stringstream的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1080638

相关文章

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

C#中字符串分割的多种方式

《C#中字符串分割的多种方式》在C#编程语言中,字符串处理是日常开发中不可或缺的一部分,字符串分割是处理文本数据时常用的操作,它允许我们将一个长字符串分解成多个子字符串,本文给大家介绍了C#中字符串分... 目录1. 使用 string.Split2. 使用正则表达式 (Regex.Split)3. 使用

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

Java中JSON字符串反序列化(动态泛型)

《Java中JSON字符串反序列化(动态泛型)》文章讨论了在定时任务中使用反射调用目标对象时处理动态参数的问题,通过将方法参数存储为JSON字符串并进行反序列化,可以实现动态调用,然而,这种方式容易导... 需求:定时任务扫描,反射调用目标对象,但是,方法的传参不是固定的。方案一:将方法参数存成jsON字

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象