stringstream的使用

std::stringstream 是C++标准库中的一个类,用于在内存中操作字符串流。它提供了一种方便的方式来格式化和解析字符串数据,类似于文件流(如 std::ifstreamstd::ofstream)但针对字符串。std::stringstream 属于 <sstream> 头文件,结合了输入(std::istringstream)和输出(std::ostringstream)的功能。

1.基本功能
  • 格式化输出:可以像使用 std::cout 一样向 std::stringstream 写入数据,然后将其作为字符串读取。
  • 字符串解析:可以将一个字符串传递给 std::stringstream,并从中解析不同的数据类型。
  • 内存中的流操作:不涉及文件操作,完全在内存中进行数据的格式化和解析。
2.常见用法

构造和赋值

#include <sstream>
#include <string>

int main() {
    // 创建一个空的 stringstream
    std::stringstream ss;

    // 用字符串初始化 stringstream
    std::string initialData = "123 456";
    std::stringstream ss2(initialData);
}

写入数据

#include <sstream>
#include <iostream>

int main() {
    std::stringstream ss;

    int num = 42;
    std::string text = "Hello, World!";

    // 向 stringstream 写入数据
    ss << num << " " << text;

    // 获取生成的字符串
    std::string result = ss.str();
    std::cout << "Generated string: " << result << std::endl;

    return 0;
}

读取数据

#include <sstream>
#include <iostream>

int main() {
    std::string data = "123 456.789 Hello";
    std::stringstream ss(data);

    int i;
    float f;
    std::string s;

    // 从 stringstream 读取数据
    ss >> i >> f >> s;

    std::cout << "Integer: " << i << std::endl;
    std::cout << "Float: " << f << std::endl;
    std::cout << "String: " << s << std::endl;

    return 0;
}

清空和重用

#include <sstream>
#include <iostream>

int main() {
    std::stringstream ss;
    ss << "Initial text";

    std::cout << "Before clearing: " << ss.str() << std::endl;

    // 清空内容并重用
    ss.str("");
    ss.clear();
    ss << "New text";

    std::cout << "After clearing: " << ss.str() << std::endl;

    return 0;
}
3.常见的操作
  • str():获取或设置 stringstream 中的字符串。
  • clear():重置流的状态标志。
  • seekg()seekp():调整流中读写指针的位置。
#include <sstream>
#include <iostream>

int main() {
    std::stringstream ss("1234");

    // 读取第一个字符
    char c;
    ss >> c;
    std::cout << "First char: " << c << std::endl; // 1

    // 移动读指针到起始位置
    ss.seekg(3);

    // 读取第一个字符
    ss >> c;
    std::cout << "First char after seekg: " << c << std::endl; // 4

    return 0;
}
4.适用场景
  • 字符串拼接和格式化:代替 sprintf 或手动字符串拼接操作,更加类型安全。
  • 解析复杂字符串:从一个字符串中提取并解析多个数据字段。
  • 内存中的流处理:无需文件I/O操作,适合处理小型数据或临时数据。
5.示例:解析复杂字符串
#include <sstream>
#include <iostream>

int main() {
    std::string data = "42 3.14 Hello World";
    std::stringstream ss(data);

    int integer;
    float real;
    std::string firstWord, secondWord;

    ss >> integer >> real >> firstWord >> secondWord;

    std::cout << "Integer: " << integer << std::endl;
    std::cout << "Float: " << real << std::endl;
    std::cout << "First word: " << firstWord << std::endl;
    std::cout << "Second word: " << secondWord << std::endl;

    return 0;
}
7. 线程安全

std::stringstream 不是线程安全的。如果多个线程同时访问同一个 std::stringstream 对象,必须使用适当的同步机制(如互斥锁)来防止数据竞争和不一致。

8. 相关类
  • std::istringstream:只支持输入操作的字符串流。
  • std::ostringstream:只支持输出操作的字符串流。
  • std::fstreamstd::ifstreamstd::ofstream:文件流,用于处理文件的I/O操作。
总结

std::stringstream 是一个强大的工具,用于在内存中处理字符串数据。它提供了灵活的格式化和解析功能,适合在需要频繁进行字符串操作的应用场景中使用。相比传统的C风格字符串操作,std::stringstream 提供了更安全和更便捷的接口,有助于提高代码的可读性和维护性。

具体例题例子
string discountPrices(string sentence, int discount) {
    double d = 1 - discount / 100.0;
    stringstream ss(sentence);
    string ans, w;
    while (ss >> w) { // 一边分割,一边加到答案中
        if (!ans.empty()) {
            ans += ' ';
        }
        if (w.length() > 1 && w[0] == '$' && all_of(w.begin() + 1, w.end(), ::isdigit)) {
            stringstream s;
            s << fixed << setprecision(2) << '$' << stoll(w.substr(1)) * d;
            ans += s.str();
        } else {
            ans += w;
        }
    }
    return ans;
}

解释:

std::fixed:

  • 操作流,使其以定点表示法输出浮点数。
  • 输出的浮点数总是保留固定的小数位数(由 std::setprecision 指定)。
  • 如果 std::setprecision 设置了整数部分小数点后的位数,将用0填充不足的位数。

std::setprecision:

  • 用于设置浮点数输出时的小数精度。
  • 其效果取决于当前流的浮点格式模式(例如,std::fixedstd::scientific)。
  • std::fixed 模式下,std::setprecision 控制小数点后的位数。
举例

显示两位小数

#include <iostream>
#include <iomanip>

int main() {
    double pi = 3.141592653589793;

    std::cout << std::fixed << std::setprecision(2) << pi << std::endl; // Output: 3.14

    return 0;
}
与其他格式操纵符对比
  • std::scientific
    • 将浮点数以科学计数法输出。
    • 通常用于处理非常大或非常小的数值。
#include <iostream>
#include <iomanip>

int main() {
    double value = 12345.6789;

    std::cout << std::scientific << std::setprecision(2) << value << std::endl; // Output: 1.23e+04

    return 0;
}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值