c++字符串操作之std::ostringstream踩坑日记

c++字符串操作之std::ostringstream踩坑日记

在开发过程中经常会遇到字符串操作,而std::string又没有format操作,这就很难受了。
于是我找到了std::ostringstream类;ostringstream类的用法也很简单,就是流操作。
头文件:include <sstream>
如:
int number = 14;
double ddata = 21.7;
char* pstr = "test";
std::ostringstream ostr;
ostr << "开始测试:" << std::endl;
ostr << "整形数据为:" << number << std::endl;
ostr << "浮点数为:" << ddata << std::endl;
ostr << "字符串为:" << pstr << std::endl;
std::cout << ostr.str();//str()是以std::string的形式返回

输出结果是这样的

开始测试:
整形数据为:14
浮点数为:21.7
字符串为:test

但是问题来了,通常一个变量或对象需要重复使用。那我要如何清除流中的数据呢?
一般的思路都是clear()。因为在STL容器里习惯都是clear()方法清空容器。所以第一反应都是用clear()方法来清除流中的数据。
试调用,ostr.clear();编译不报错(说明有这个方法存在,心想那就没错了,聪明的我一猜就对)。
int number = 14;
double ddata = 21.7;
char* pstr = "test";
std::ostringstream ostr;
ostr << "开始测试:" <
<think>在C++中,将字符串转换为`std::string`类型实际上是非常直接的,因为`std::string`的构造函数可以接受多种形式的字符串。下面我将详细介绍几种常见的转换情况,并给出代码示例。 ### 1. 从C风格字符串(字符数组)转换 ```cpp #include <iostream> #include <string> int main() { const char* cStr = "Hello, World!"; // C风格字符串 std::string cppStr = cStr; // 隐式转换 // 或者显式构造 std::string cppStr2(cStr); std::cout << cppStr << std::endl; // 输出: Hello, World! std::cout << cppStr2 << std::endl; // 输出: Hello, World! return 0; } ``` ### 2. 从字符数组(带长度)转换 如果字符数组不是以空字符('\0')结尾,或者我们只想转换数组的一部分,可以使用带有长度的构造函数。 ```cpp #include <iostream> #include <string> int main() { char charArray[] = {'H', 'e', 'l', 'l', 'o'}; // 不以空字符结尾 // 使用两个指针(起始和结束)来构造 std::string str1(charArray, charArray + 5); // 或者使用指针和长度 std::string str2(charArray, 5); std::cout << str1 << std::endl; // 输出: Hello std::cout << str2 << std::endl; // 输出: Hello return 0; } ``` ### 3. 从另一个字符串的子串转换 ```cpp #include <iostream> #include <string> int main() { std::string original = "Hello, World!"; // 获取子串,从索引7开始,长度为5 std::string sub = original.substr(7, 5); std::cout << sub << std::endl; // 输出: World return 0; } ``` ### 4. 从数字转换(整数、浮点数) 通常我们需要将数字转换为字符串,可以使用`std::to_string`函数。 ```cpp #include <iostream> #include <string> int main() { int num = 42; double pi = 3.14159; std::string numStr = std::to_string(num); std::string piStr = std::to_string(pi); std::cout << numStr << std::endl; // 输出: 42 std::cout << piStr << std::endl; // 输出: 3.141590(注意精度) // 如果需要控制精度,可以使用其他方法(如stringstream) return 0; } ``` ### 5. 使用字符串流(stringstream)进行复杂的转换 当需要更复杂的格式化(如控制浮点数精度)时,可以使用`std::stringstream`。 ```cpp #include <iostream> #include <string> #include <sstream> #include <iomanip> // 用于setprecision int main() { double pi = 3.1415926535; std::stringstream ss; ss << std::fixed << std::setprecision(2) << pi; std::string piStr = ss.str(); std::cout << piStr << std::endl; // 输出: 3.14 return 0; } ``` ### 6. 从字符转换(单个字符) ```cpp #include <iostream> #include <string> int main() { char ch = 'A'; std::string str(1, ch); // 构造一个包含1个字符ch的字符串 std::cout << str << std::endl; // 输出: A return 0; } ``` ### 7. 从宽字符串转换(wchar_t, char16_t, char32_t) 如果需要将宽字符字符串(如wchar_t)转换为std::string,可以使用编码转换。但注意这涉及到编码问题,通常需要特定的转换函数(如使用<codecvt>头文件,但C++17已弃用,建议使用其他库如ICU)。这里给出一个简单示例(仅适用于ASCII字符): ```cpp #include <iostream> #include <string> #include <locale> #include <codecvt> // C++11有,但C++17弃用,需注意 int main() { std::wstring wideStr = L"Hello, Wide World!"; // 使用wstring_convert(C++11,但C++17弃用) std::wstring_convert<std::codecvt_utf8<wchar_t>> converter; std::string narrowStr = converter.to_bytes(wideStr); std::cout << narrowStr << std::endl; // 在C++20中,可以使用std::u8string和新的转换方法 // 但这里不展开 return 0; } ``` **注意**:对于宽字符转换,由于编码问题,上述方法可能不适用于所有情况,特别是非ASCII字符(如中文)。在生产环境中,建议使用专门的库(如ICU)来处理编码转换。 ### 总结 - 大多数情况下,直接赋值或构造即可将C风格字符串转换为`std::string`。 - 对于数字转换,使用`std::to_string`或`std::stringstream`。 - 对于子串,使用`substr`方法。 - 宽字符转换需要谨慎处理编码问题。 §§相关问题§§: 1. 如何将 `std::string` 转换为 C 风格字符串(`const char*`)? 2. 在 C++ 中如何安全地处理不同编码的字符串转换(如 UTF-8 与宽字符)? 3. 使用 `std::to_string` 转换浮点数时如何控制小数位数? 4. 如何将多个字符串连接成一个 `std::string`?</think># 在 C++ 中将字符串转换为 std::string 类型 在 C++ 中,`std::string` 是标准库提供的字符串类,用于高效地处理和操作字符串。下面我将详细介绍如何将各种类型的字符串表示转换为 `std::string` 类型,并提供代码示例。 ## 1. 从 C 风格字符串(字符数组)转换 ```cpp #include <iostream> #include <string> int main() { // 从 C 风格字符串转换 const char* cstr = "Hello from C-style string"; std::string str1 = cstr; // 隐式转换 std::string str2(cstr); // 显式构造函数 std::cout << "str1: " << str1 << std::endl; std::cout << "str2: " << str2 << std::endl; return 0; } ``` **解释**: - C 风格字符串是 `const char*` 类型,以空字符 `\0` 结尾 - `std::string` 提供了接受 `const char*` 的构造函数和赋值运算符 - 转换是自动的,不需要特殊处理 ## 2. 从字符数组(非空终止)转换 ```cpp #include <iostream> #include <string> #include <cstring> int main() { // 非空终止的字符数组 char charArray[] = {'H', 'e', 'l', 'l', 'o'}; // 使用两个迭代器构造 std::string str1(charArray, charArray + sizeof(charArray)); // 使用指针和长度构造 std::string str2(charArray, sizeof(charArray)); std::cout << "str1: " << str1 << std::endl; // 输出: Hello std::cout << "str2: " << str2 << std::endl; // 输出: Hello return 0; } ``` **解释**: - 当字符数组不以空字符结尾时,需要指定长度 - 使用 `std::string(const char* s, size_t n)` 构造函数 - 或者使用迭代器范围 `std::string(InputIt first, InputIt last)` ## 3. 从数值类型转换 ### 使用 std::to_string ```cpp #include <iostream> #include <string> int main() { int num = 42; double pi = 3.14159; std::string numStr = std::to_string(num); std::string piStr = std::to_string(pi); std::cout << "Number: " << numStr << std::endl; // 输出: 42 std::cout << "Pi: " << piStr << std::endl; // 输出: 3.141590 return 0; } ``` ### 使用字符串流(更灵活) ```cpp #include <iostream> #include <string> #include <sstream> #include <iomanip> // 用于格式化 int main() { double price = 19.99; int quantity = 5; std::ostringstream oss; oss << "Total: $" << std::fixed << std::setprecision(2) << (price * quantity); std::string result = oss.str(); std::cout << result << std::endl; // 输出: Total: $99.95 return 0; } ``` **解释**: - `std::to_string` 简单但格式化选项有限 - `std::ostringstream` 提供更强大的格式化功能 - 使用 `str()` 方法获取最终的 `std::string` ## 4. 从宽字符串(wchar_t)转换 ```cpp #include <iostream> #include <string> #include <locale> #include <codecvt> int main() { // 宽字符串(如来自Windows API) const wchar_t* wideStr = L"你好,世界!"; // 使用C++11的codecvt转换(C++17已弃用,但可用) std::wstring_convert<std::codecvt_utf8<wchar_t>> converter; std::string narrowStr = converter.to_bytes(wideStr); std::cout << narrowStr << std::endl; // 输出: 你好,世界! return 0; } ``` **注意**:C++17 弃用了 `<codecvt>`,在 C++20 中可以使用以下替代方法: ```cpp #include <iostream> #include <string> #include <locale> #include <clocale> int main() { std::setlocale(LC_ALL, "en_US.utf8"); const wchar_t* wideStr = L"Hello, 世界!"; // 计算所需缓冲区大小 size_t len = std::wcslen(wideStr); size_t maxBytes = len * 4; // UTF-8最多4字节/字符 char buffer[256]; std::wcstombs(buffer, wideStr, maxBytes); std::string narrowStr(buffer); std::cout << narrowStr << std::endl; // 输出: Hello, 世界! return 0; } ``` ## 5. 从 std::string_view 转换 ```cpp #include <iostream> #include <string> #include <string_view> int main() { const char* cstr = "Hello from string_view"; std::string_view sv(cstr); // 直接构造 std::string str1(sv); // 使用范围构造 std::string str2(sv.begin(), sv.end()); std::cout << "str1: " << str1 << std::endl; std::cout << "str2: " << str2 << std::endl; return 0; } ``` **解释**: - `std::string_view` (C++17) 是字符串的非拥有视图 - 可以直接转换为 `std::string` - 转换会复制数据,创建新的字符串对象 ## 6. 从其他字符类型转换 ```cpp #include <iostream> #include <string> #include <cctype> // 用于字符转换 int main() { // 从字符数组转换并处理大小写 char mixedCase[] = "HeLLo WoRLd"; std::string lowerStr; for (char c : mixedCase) { if (c == '\0') break; // 空终止检查 lowerStr += std::tolower(static_cast<unsigned char>(c)); } std::cout << lowerStr << std::endl; // 输出: hello world return 0; } ``` ## 7. 使用用户定义字面量(C++14) ```cpp #include <iostream> #include <string> // 定义字面量运算符 std::string operator"" _s(const char* str, std::size_t len) { return std::string(str, len); } int main() { // 使用自定义字面量 auto str = "This is a string literal"_s; // 验证类型 static_assert(std::is_same_v<decltype(str), std::string>, "Type is not std::string"); std::cout << str << std::endl; return 0; } ``` **解释**: - 用户定义字面量提供更自然的语法 - 运算符 `"" _s` 将字符串字面量直接转换为 `std::string` - 需要 C++14 或更高版本 ## 总结 在 C++ 中将字符串转换为 `std::string` 有多种方法: 1. 从 C 风格字符串:直接赋值或构造 2. 从字符数组:指定长度或使用迭代器 3. 从数值:使用 `std::to_string` 或字符串流 4. 从宽字符串:使用转换工具或标准库函数 5. 从 `string_view`:直接构造 6. 自定义转换:处理特殊需求 7. 用户定义字面量:提供更自然的语法 选择哪种方法取决于源字符串的类型和所需的转换操作。对于大多数情况,直接构造或赋值是最简单的方法。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值