c++拼接字符串效率比较(+=、append、stringstream、sprintf)

<think>我们使用std::stringstream进行字符串拼接。它提供类似于输入/输出流的操作,但针对字符串。可以避免频繁的内存分配,提高效率。以下是详细的使用方法代码示例:</think> ### 使用 `std::stringstream` 实现高效字符串拼接 `std::stringstream` 是 C++ 标准库中 `<sstream>` 头文件提供的流类,它结合了 `iostream` 的格式化功能 `string` 的字符串处理能力,是进行复杂字符串拼接的理想工具。 #### 基本使用示例 ```cpp #include <iostream> #include <sstream> #include <string> int main() { // 创建字符串流对象 std::stringstream ss; // 使用流操作符拼接不同类型的数据 ss << "当前时间: " << 2023 << "-" << 12 << "-" << 15; ss << " 温度: " << 25.5 << "℃"; // 获取拼接后的字符串 std::string result = ss.str(); std::cout << result << std::endl; return 0; } ``` 输出: ``` 当前时间: 2023-12-15 温度: 25.5℃ ``` #### 高级特性与应用 ##### 1. 重置字符串流内容 ```cpp ss.str(""); // 清空内容 ss.clear(); // 清除错误状态标志 ``` ##### 2. 转换数据类型 ```cpp std::string input = "42 3.14 hello"; std::stringstream converter(input); int num; double pi; std::string text; converter >> num >> pi >> text; std::cout << num << ", " << pi << ", " << text << std::endl; ``` ##### 3. 格式化输出(类似 sprintf) ```cpp int hour = 14, minute = 30; std::stringstream time_ss; time_ss << std::setfill('0') // 设置填充字符 << std::setw(2) << hour // 设置宽度 << ":" << std::setw(2) << minute; std::cout << "格式化时间: " << time_ss.str() << std::endl; // 输出: 格式化时间: 14:30 ``` ##### 4. 构建复杂字符串 ```cpp struct Person { std::string name; int age; }; std::vector<Person> people = {{"Alice", 30}, {"Bob", 25}}; std::stringstream json; json << "[\n"; for (size_t i = 0; i < people.size(); ++i) { json << " {\"name\": \"" << people[i].name << "\", \"age\": " << people[i].age << "}"; if (i < people.size() - 1) json << ",\n"; } json << "\n]"; std::cout << json.str() << std::endl; ``` 输出: ``` [ {"name": "Alice", "age": 30}, {"name": "Bob", "age": 25} ] ``` #### 性能优化建议 1. **预分配内存**:减少重新分配次数 ```cpp std::stringstream ss; ss.str(); // 触发初始分配 ss << "初始内容"; ``` 2. **复用流对象**:避免频繁创建销毁 ```cpp static std::stringstream reusable_ss; reusable_ss.str(""); reusable_ss.clear(); ``` 3. **批量处理**:减少流操作次数 ```cpp // 不推荐(多次流操作) ss << a; ss << b; ss << c; // 推荐(单次流操作) ss << a << b << c; ``` 4. **使用 `std::ostringstream`**:当不需要输入操作时 ```cpp #include <sstream> std::ostringstream oss; // 仅输出 oss << "更高效的拼接"; ``` #### 与替代方案的比较 | 方法 | 优点 | 缺点 | |---------------------|-------------------------------|--------------------------| | `stringstream` | 类型安全,支持格式化,可读性好 | 中等性能 | | `operator+` | 简单直观 | 性能差(临时对象) | | `std::format`(C++20)| 高性能,简洁语法 | 需C++20支持 | | `append()` | 高性能 | 代码冗长,无类型转换 | | `sprintf()` | C兼容性 | 不安全,易发生缓冲区溢出 | #### 完整实用示例 ```cpp #include <iostream> #include <sstream> #include <iomanip> class Logger { public: enum LogLevel { INFO, WARNING, ERROR }; Logger(LogLevel level) : level_(level) { ss_ << timestamp() << " [" << levelToString(level_) << "] "; } template <typename T> Logger& operator<<(const T& value) { ss_ << value; return *this; } ~Logger() { if (level_ >= WARNING) { std::cerr << ss_.str() << std::endl; } else { std::cout << ss_.str() << std::endl; } } private: std::string timestamp() const { std::time_t t = std::time(nullptr); std::tm tm = *std::localtime(&t); std::ostringstream oss; oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S"); return oss.str(); } std::string levelToString(LogLevel level) const { switch(level) { case INFO: return "INFO"; case WARNING: return "WARN"; case ERROR: return "ERROR"; default: return "UNKNOWN"; } } LogLevel level_; std::ostringstream ss_; }; #define LOG_INFO() Logger(Logger::INFO) #define LOG_WARN() Logger(Logger::WARNING) #define LOG_ERROR() Logger(Logger::ERROR) int main() { LOG_INFO() << "应用启动,版本: " << 1.0; int items = 5; if (items > 3) { LOG_WARN() << "项目数量(" << items << ")超过阈值"; } try { throw std::runtime_error("测试错误"); } catch (const std::exception& e) { LOG_ERROR() << "捕获异常: " << e.what() << " (代码位置: " << __FILE__ << ":" << __LINE__ << ")"; } return 0; } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值