stringstream,string和char *转换混淆 [英] stringstream, string, and char* conversion confusion

查看:122
本文介绍了stringstream,string和char *转换混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题可以归结到, 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆