stringstream,string和char *转换混淆 [英] stringstream, string, and char* conversion confusion
问题描述
我的问题可以归结到, stringstream.str()返回的字符串在哪里c_str()
活在内存中,为什么不能分配给 const char *
?
此代码示例将会比我更好地解释
#include< string>
#include< sstream>
#include< iostream>
using namespace std;
int main()
{
stringstream ss(this is a string\\\
);
string str(ss.str());
const char * cstr1 = str.c_str();
const char * cstr2 = ss.str()。c_str();
cout<< cstr1 //正确打印
<< cstr2; // ERROR,prints out garbage
system(PAUSE);
return 0;
}
假设 stringstream.str ()
可以分配给一个 const char *
,导致我花了一段时间来跟踪一个错误。
对于奖励积分,任何人都可以解释为什么用
$ b <$ p $替换 cout
语句p> cout<< cstr //正确打印
<< ss.str()。c_str()//正确打印
<< cstr2; //正确打印(???)
正确打印字符?
我在Visual Studio 2008中编译。
stringstream。 str()
返回在完整表达式结尾处销毁的临时字符串对象。如果你从( stringstream.str()。c_str()
)得到一个指向C字符串的指针,它将指向一个在语句结束处被删除的字符串。这就是为什么你的代码打印垃圾。
您可以将该临时字符串对象复制到其他字符串对象,并从该字符串取出C字符串:
const std :: string tmp = stringstream.str();
const char * cstr = tmp.c_str();请注意,我创建了临时字符串 const
$ b < ,因为对它的任何更改可能导致它重新分配,从而使 cstr
无效。因此,更安全的是不存储调用 str()
的结果,并使用 cstr
完整表达式的结尾:
use_c_str(stringstream.str
当然,后者可能不容易,复制可能太贵。你可以做的是将临时绑定到 const
引用。这将延长其生命周期到引用的生命周期:
{
const std :: string& tmp = stringstream.str();
const char * cstr = tmp.c_str();
}
IMO是最好的解决方案。不幸的是,它不是很知名。
My question can be boiled down to, where does the string returned from stringstream.str().c_str()
live in memory, and why can't it be assigned to a const char*
?
This code example will explain it better than I can
#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;
}
The assumption that stringstream.str().c_str()
could be assigned to a const char*
led to a bug that took me a while to track down.
For bonus points, can anyone explain why replacing the cout
statement with
cout << cstr // Prints correctly
<< ss.str().c_str() // Prints correctly
<< cstr2; // Prints correctly (???)
prints the strings correctly?
I'm compiling in Visual Studio 2008.
stringstream.str()
returns a temporary string object that's destroyed at the end of the full expression. If you get a pointer to a C string from that (stringstream.str().c_str()
), it will point to a string which is deleted where the statement ends. That's why your code prints garbage.
You could copy that temporary string object to some other string object and take the C string from that one:
const std::string tmp = stringstream.str();
const char* cstr = tmp.c_str();
Note that I made the temporary string const
, because any changes to it might cause it to re-allocate and thus render cstr
invalid. It is therefor safer to not to store the result of the call to str()
at all and use cstr
only until the end of the full expression:
use_c_str( stringstream.str().c_str() );
Of course, the latter might not be easy and copying might be too expensive. What you can do instead is to bind the temporary to a const
reference. This will extend its lifetime to the lifetime of the reference:
{
const std::string& tmp = stringstream.str();
const char* cstr = tmp.c_str();
}
IMO that's the best solution. Unfortunately it's not very well known.
这篇关于stringstream,string和char *转换混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!