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调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

C/C++错误信息处理的常见方法及函数

《C/C++错误信息处理的常见方法及函数》C/C++是两种广泛使用的编程语言,特别是在系统编程、嵌入式开发以及高性能计算领域,:本文主要介绍C/C++错误信息处理的常见方法及函数,文中通过代码介绍... 目录前言1. errno 和 perror()示例:2. strerror()示例:3. perror(

C++变换迭代器使用方法小结

《C++变换迭代器使用方法小结》本文主要介绍了C++变换迭代器使用方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、源码2、代码解析代码解析:transform_iterator1. transform_iterat

详解C++中类的大小决定因数

《详解C++中类的大小决定因数》类的大小受多个因素影响,主要包括成员变量、对齐方式、继承关系、虚函数表等,下面就来介绍一下,具有一定的参考价值,感兴趣的可以了解一下... 目录1. 非静态数据成员示例:2. 数据对齐(Padding)示例:3. 虚函数(vtable 指针)示例:4. 继承普通继承虚继承5.

C++中std::distance使用方法示例

《C++中std::distance使用方法示例》std::distance是C++标准库中的一个函数,用于计算两个迭代器之间的距离,本文主要介绍了C++中std::distance使用方法示例,具... 目录语法使用方式解释示例输出:其他说明:总结std::distance&n编程bsp;是 C++ 标准

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

C++ 中的 if-constexpr语法和作用

《C++中的if-constexpr语法和作用》if-constexpr语法是C++17引入的新语法特性,也被称为常量if表达式或静态if(staticif),:本文主要介绍C++中的if-c... 目录1 if-constexpr 语法1.1 基本语法1.2 扩展说明1.2.1 条件表达式1.2.2 fa

python中字符串拼接的几种方法及优缺点对比详解

《python中字符串拼接的几种方法及优缺点对比详解》在Python中,字符串拼接是常见的操作,Python提供了多种方法来拼接字符串,每种方法有其优缺点和适用场景,以下是几种常见的字符串拼接方法,需... 目录1. 使用 + 运算符示例:优缺点:2. 使用&nbsjsp;join() 方法示例:优缺点:3

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注