我们在 sstream 头文件中定义了三个类型来支持内存IO(ostringstream\istringstream\stringstream),这些类型可以向 string 写入数据,这里我们主要讲: std::ostringstream
和 std::istringstream
( C++ Primer 中文版第五版)
以上的两个类型都继承自我们经常使用的 iostream 头文件中定义的类型。并且,他们还增加了一下成员来管理与流相关的 string。
也就是说,他们使得我们能够像控制IO流一样控制 string。
常用方法:
它有一个很典型的场景:
逐步构造输出,希望最后一起打印时,ostringstream
非常有用。
比如逐个验证电话号码并改变其格式等等。
这里就典型使用到了我们的逐步构造输出,希望最后一起打印。
std::string serialize(TreeNode* root) {
std::ostringstream out;
if (!root) {
out << "null ";
} else {
out << root->val << " ";
out << serialize(root->left);
out << serialize(root->right);
}
return out.str();
}
这个也是,我们的逐步构造输出,希望最后一起打印。
#include
#include
int main () {
std::ostringstream out;
int number = 42;
std::string text = "The answer is";
out << text << " " << number << ".";
std::string result = out.str();
std::cout << result << std::endl; // 输出:The answer is 42.
return 0;
}
当需要对输出进行格式化(例如控制浮点数的小数位数、控制数字格式等),ostringstream 可以帮助我们简化这类操作。
#include
#include
#include // 控制浮点数京都
int main () {
std::ostringstream out;
double pi = 3.14159265358979323;
// 设置京都为小数点后两位
out << std::fixed << std::setprecision(2) << pi;
std::out << "Formatted pi: " << out.str() << std::endl;
return 0;
}
int main () {
std::string inpit = "42 3.14 Hello";
std::istringstream iss(input);
int number;
double pi;
std::string text;
iss >> number >> pi >> text;
}
注意,我们的 >> 操作符更适合用于逐个提取空格分隔的值。
这里我们列举一个 getline 的用法:
// getline 读取文件内容
int main () {
std::ifstream file("input.txt");
std::string line;
if (file.is_open()) {
while (std::getline(file, line)) {
std::cout << line << std::endl; //输出每行内容,getline 会逐行读取,直到遇到文件结束或换行符
}
file.close();
} else {
std::cerr << "Unable to open file" << std::endl;
}
return 0;
}
// getline 自定义分隔符号
int main () {
std::string input = "apple,banana,orange,grape";
std::istringstream stream(input);
std::string token;
while (std::getline(stream, token, ',')) {
std::cout << "Extracted token: " << token << std::endl;
}
}
TreeNode* deserialize(std::istringstream& iss) {
std::string val;
iss >> val;
if (val == "null") {
return nullptr;
}
TreeNode* node = new TreeNode(std::stoi(val));
node->left = deserialize(iss);
node->right = deserialize(iss);
return node;
}
int main () {
std::string data = "1 2 null null 3 null null";
std::istringstream iss(data);
TreeNode* root = deserialize(iss);
std:: cout << "Deserialized tree root value: " << root->val << std::endl;
}