我的问题可以归结为,从 stringstream.str().c_str()
返回的字符串在哪里存在内存中,为什么不能将它分配给 const char*
?
这个代码示例将比我解释得更好
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
stringstream ss("this is a string\n");
string str(ss.str());
const char* cstr1 = str.c_str();
const char* cstr2 = ss.str().c_str();
cout << cstr1 // Prints correctly
<< cstr2; // ERROR, prints out garbage
system("PAUSE");
return 0;
}
stringstream.str().c_str()
可以分配给 const char*
的假设导致了我花了一段时间才找到的错误。
对于奖励积分,谁能解释为什么用
替换cout
语句
cout << cstr // Prints correctly
<< ss.str().c_str() // Prints correctly
<< cstr2; // Prints correctly (???)
正确打印字符串?
我在 Visual Studio 2008 中编译。
最佳答案
stringstream.str()
返回一个临时字符串对象,该对象在完整表达式的末尾被销毁。如果您从该 (stringstream.str().c_str()
) 获得指向 C 字符串的指针,它将指向语句结束处被删除的字符串。这就是您的代码打印垃圾的原因。
您可以将该临时字符串对象复制到其他字符串对象并从中获取 C 字符串:
const std::string tmp = stringstream.str();
const char* cstr = tmp.c_str();
请注意,我创建了临时字符串 const
,因为对它的任何更改都可能导致它重新分配,从而使 cstr
无效。因此,完全不存储对 str()
的调用结果并仅在完整表达式结束之前使用 cstr
会更安全:
use_c_str( stringstream.str().c_str() );
当然,后者可能并不容易,而且复制成本可能太高。您可以做的是将临时绑定(bind)到 const
引用。这会将其生命周期延长到引用的生命周期:
{
const std::string& tmp = stringstream.str();
const char* cstr = tmp.c_str();
}
IMO 这是最好的解决方案。不幸的是,它不是很为人所知。
关于c++ - stringstream、string 和 char* 转换混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1374468/