目录
- 一、
<sstream>
头文件概述 - 二、
<sstream>
中的主要元素及使用场景- 2.1 字符串流类
- 2.2 输入输出操作函数
- 2.3 格式化和解析函数
- 三、元素的详细用法及代码示例
- 3.1 字符串流类的使用
- 3.2 输入输出操作函数的使用
- 3.3 格式化和解析函数的使用
- 四、机器人 SLAM 中的应用实例
- 4.1 数据存储和转换
- 4.2 日志记录和消息传递
-
拓展知识:std::stringstream 和 std::ostringstream区别?
一、<sstream>
头文件概述
<sstream>
是 C++ 标准库中的一个头文件。它主要提供了字符串流(string stream)相关的类和函数,用于在字符串和其他数据类型之间进行转换,以及对字符串进行输入输出操作。它包含一些模板类和模板函数,这些类和函数允许将字符串作为流来处理,就像处理文件流或标准输入输出流一样。
二、<sstream>
中的主要元素及使用场景
2.1 字符串流类:
- std::stringstream
:
- 既可以作为输入流,也可以作为输出流。
- 使用场景:当需要将各种数据类型转换为字符串,或者将字符串解析为不同的数据类型,并且可能需要对字符串进行中间处理时使用。
- std::istringstream
:
- 主要作为输入字符串流,从字符串中读取数据。
- 使用场景:当有一个字符串,需要从中提取数据时,例如解析配置信息或解析输入的文本数据。
- std::ostringstream
:
- 主要作为输出字符串流,将数据写入到字符串中。
- 使用场景:当需要将多个数据组合成一个字符串,如格式化输出、日志信息的生成等。
2.2 输入输出操作函数:
- operator<<
:
- 用于将数据插入到输出字符串流中。
- 使用场景:在 ostringstream
中,将数据输出到字符串,支持多种数据类型,如整数、浮点数、字符串等。
- operator>>
:
- 用于从输入字符串流中提取数据。
- 使用场景:在 istringstream
中,从字符串中读取不同类型的数据,如解析配置文件或从字符串输入中提取信息。
2.3 格式化和解析函数:
- str()
:
- 获取或设置字符串流的内容。
- 使用场景:将最终的字符串流内容提取为字符串,或者用一个新的字符串初始化字符串流。
- clear()
:
- 清除错误标志和内容。
- 使用场景:在重复使用字符串流时,清除之前的状态和内容,确保正常操作。
三、元素的详细用法及代码示例
3.1 字符串流类的使用:
#include <iostream>
#include <sstream>
#include <string>
int main() {
std::stringstream ss;
ss << "Hello, " << 42 << " World!";
std::string result = ss.str();
std::cout << result << std::endl;
return 0;
}
- 代码解释:
- 创建
std::stringstream
对象ss
。 - 使用
operator<<
将字符串和整数插入到ss
中。 - 使用
str()
函数获取存储在ss
中的字符串。
- 创建
3.2 输入输出操作函数的使用:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
int main() {
std::string input = "1 2 3 4 5";
std::istringstream iss(input);
std::vector<int> numbers;
int num;
while (iss >> num) {
numbers.push_back(num);
}
for (int n : numbers) {
std::cout << n << " ";
}
std::cout << std::endl;
return 0;
}
- 代码解释:
- 创建
std::istringstream
对象iss
并初始化为input
字符串。 - 使用
operator>>
从iss
中读取整数,并存储到numbers
向量中。
- 创建
3.3 格式化和解析函数的使用:
#include <iostream>
#include <sstream>
#include <string>
int main() {
std::ostringstream oss;
oss << std::fixed << std::setprecision(2) << 3.14159;
std::string formatted = oss.str();
std::cout << formatted << std::endl;
oss.str(""); // 清除内容
oss << "New content";
std::cout << oss.str() << std::endl;
return 0;
}
- 代码解释:
- 使用
std::ostringstream
进行格式化输出,将浮点数3.14159
格式化为固定小数位的字符串。 - 使用
str("")
清除内容并设置新内容。
- 使用
四、机器人 SLAM 中的应用实例
4.1 数据存储和转换:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
class SensorData {
private:
std::vector<double> data;
public:
void addData(double d) { data.push_back(d); }
std::string serialize() {
std::ostringstream oss;
for (size_t i = 0; i < data.size(); ++i) {
oss << data[i];
if (i < data.size() - 1) oss << ",";
}
return oss.str();
}
void deserialize(const std::string& str) {
std::istringstream iss(str);
double d;
while (iss >> d) {
data.push_back(d);
char comma;
if (iss >> comma) continue; // 跳过逗号
}
}
};
int main() {
SensorData sensorData;
sensorData.addData(1.0);
sensorData.addData(2.0);
sensorData.addData(3.0);
std::string serialized = sensorData.serialize();
std::cout << "Serialized data: " << serialized << std::endl;
SensorData newSensorData;
newSensorData.deserialize(serialized);
std::cout << "Deserialized data: ";
for (double d : newSensorData.data) {
std::cout << d << " ";
}
std::cout << std::endl;
return 0;
}
- 代码解释:
SensorData
类使用serialize
方法将数据序列化为一个逗号分隔的字符串。deserialize
方法将字符串解析为数据并存储到data
向量中。
4.2 日志记录和消息传递:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
class SLAMSystem {
private:
std::ostringstream logStream;
public:
void log(const std::string& message) {
logStream << "LOG: " << message << std::endl;
}
std::string getLog() {
return logStream.str();
}
};
int main() {
SLAMSystem slamSystem;
slamSystem.log("Initializing SLAM");
slamSystem.log("Processing sensor data");
std::cout << slamSystem.getLog();
return 0;
}
- 代码解释:
SLAMSystem
类使用logStream
存储日志信息。log
方法添加日志信息,getLog
方法获取存储的日志。
在机器人 SLAM 中,以下元素的使用频率比较高:
std::stringstream
和std::ostringstream
:- 用于将各种数据类型转换为字符串,在数据存储、日志记录和消息传递中非常有用,方便数据的序列化和信息的格式化。
std::istringstream
:- 在解析数据时,例如从配置文件、传感器数据的字符串表示中提取信息,是常用的工具。
<sstream>
头文件提供了强大的字符串流功能,使 C++ 程序能够方便地在字符串和其他数据类型之间进行转换和操作。在机器人 SLAM 中,这些功能有助于数据存储、日志记录和信息的解析与格式化,提高了代码的灵活性和可读性。
拓展知识:std::stringstream 和 std::ostringstream区?
一、基本区别
-
功能特性:
-
std::stringstream
:- 是一个功能更全面的字符串流类,它可以同时作为输入流和输出流使用。这意味着你可以使用
operator>>
从stringstream
中读取数据,也可以使用operator<<
向其中写入数据。 - 适用于需要对字符串进行复杂操作,既需要解析其中的数据,又需要向其中添加新数据的场景。
- 是一个功能更全面的字符串流类,它可以同时作为输入流和输出流使用。这意味着你可以使用
-
std::ostringstream
:- 是一个仅用于输出的字符串流类,只能使用
operator<<
向其中添加数据,而不能使用operator>>
从其中读取数据。 - 主要用于将不同类型的数据组合成一个字符串,是生成字符串的得力工具,例如将多个数据拼接、格式化输出信息等。
- 是一个仅用于输出的字符串流类,只能使用
-
-
使用场景示例:
std::stringstream
的使用场景:
#include <iostream>
#include <sstream>
#include <string>
int main() {
std::stringstream ss;
ss << "123 456"; // 向 stringstream 中写入数据
int num1, num2;
ss >> num1 >> num2; // 从 stringstream 中读取数据
std::cout << "num1: " << num1 << ", num2: " << num2 << std::endl; // 输出读取的数据
ss << " new data"; // 再次向 stringstream 中写入数据
std::string str = ss.str(); // 获取存储在 stringstream 中的字符串
std::cout << "str: " << str << std::endl; // 输出存储的字符串
return 0;
}
- 代码解释:
-
首先,使用
operator<<
向ss
中写入字符串"123 456"
。 -
然后,使用
operator>>
从ss
中读取两个整数num1
和num2
并输出。 -
接着,使用
operator<<
向ss
中添加新数据" new data"
。 -
最后,使用
str()
函数获取存储在ss
中的完整字符串并输出。 -
std::ostringstream
的使用场景:
-
#include <iostream>
#include <sstream>
#include <string>
int main() {
std::ostringstream oss;
oss << "The value of pi is approximately " << 3.14159 << "."; // 向 ostringstream 中写入数据
std::string str = oss.str(); // 获取存储在 ostringstream 中的字符串
std::cout << str << std::endl; // 输出存储的字符串
return 0;
}
- 代码解释:
- 创建
std::ostringstream
对象oss
。 - 使用
operator<<
将字符串和浮点数组合成一个完整的字符串。 - 使用
str()
函数获取存储在oss
中的字符串。
- 创建
二、使用方法和限制
-
操作符使用:
-
std::stringstream
:- 可自由使用
operator>>
和operator<<
,允许在输入和输出操作之间灵活切换。 - 由于可以进行输入操作,需要注意输入数据的格式和提取数据的顺序,以确保数据的正确解析。
- 可自由使用
-
std::ostringstream
:- 只能使用
operator<<
操作符添加数据,不能从该流中读取数据。
- 只能使用
-
-
错误处理和状态检查:
-
std::stringstream
:- 可以使用
fail()
、bad()
、eof()
等函数来检查输入输出操作的状态,确保数据读取或写入过程中没有出现错误。 - 当作为输入流使用时,可能需要根据不同的数据类型和格式进行异常处理,如提取数据失败时的处理。
- 可以使用
-
std::ostringstream
:- 主要关注输出操作,错误通常较少发生,但在使用
str()
函数时,要注意字符串长度的限制和可能的内存分配问题。
- 主要关注输出操作,错误通常较少发生,但在使用
-