如何从std string (c_str())设置char *值(不起作用)

5
我不知道,但这对我没用。当我尝试从返回std string的函数中设置char *值时,我得到了垃圾值:
string foo()
{
  string tmp ="dummy value";
  return tmp;
}

char* cc = (char *) foo().c_str(); // if i remove the casting im getting error 
// when i print the cc i get garbage 
printf("%s",cc);
5个回答

13

cc所指向的数据的生命周期与它来自的字符串的生命周期相同(最好情况下,如果你修改了字符串,它的生命周期甚至更短)。

在你的情况下,foo()的返回值是一个临时对象,在初始化cc结束时被销毁。

为了避免char *cc = foo().c_str()中的编译错误,你不应该将其强制转换为char*,而应该改成const char *cc,因为c_str()返回的是const char*。然而,这仍然没有解决主要问题。

最简单的解决方法是:

printf("%s", foo().c_str()); // if you don't need the value again later

const string s = foo();
const char *cc = s.c_str();  // if you really want the pointer - since it's
                             // in the same scope as s, and s is const,
                             // the data lives as long as cc's in scope.

string s = foo();
printf("%s", s.c_str());     // if you don't store the pointer,
                             // you don't have to worry about it.

std::cout << foo(); // printf isn't bringing much to this party anyway.

9
< p > foo 的结果是一个临时对象,在 char * cc = ... 行结束时被销毁。将其存储为常量引用:

const string& cc = foo();
printf ("%s", cc.c_str());

完全正确;const reference 延长 rvalue 的生命周期是一条奇特的规则,仅记住 也可以(可能在 C++11 中通过移动语义进行优化)。 - xtofl
只要使用移动语义或 RVO,值类型基本上是等效的。但是引用会阻止我们依赖编译器优化。 - Xion
@xtofl:如果使用foo()作为初始化程序存储值,则不需要移动语义。无聊的老旧C++03复制省略将完成它。 - Steve Jessop
+1表示解释代码存在的问题并提供“更好的解决方案” :-) - ds27680

1
将一个内存位置传递给foo(),并让foo修改它:
void foo (string* _out_newStr)
{
    _out_newStr->assign("dummy string"); //This is wrong -> _out_newStr = "dummy string";
    return;
}

当你使用字符串对象的 "c_str()" 函数时,将返回一个 const char* 值,就像已经指出的那样。

@Nawaz 很有帮助...能详细解释一下吗?我也愿意学习。 - Dennis
@Dennis:_out_newStr 是一个指向 std::string 的指针,你怎么能将字符字面量赋值给它呢?你的代码甚至无法编译。 - Nawaz
2
即使你将其更改为 *_out_damned_spot = "dummy string",在C++中使用单个输出参数是一种试图进行的优化,通常是不必要的。这可能比依赖RVO更慢,因为调用者必须创建一个空字符串,然后再将其分配给它,而有足够的复制省略时,调用者的字符串可以直接从文字构造。除非有证据表明需要返回值,否则只需通过值返回即可。 - Steve Jessop
@Nawaz:你说得对,我错了。向原帖作者道歉。实际上,由于我所从事的项目年代久远,已经有大约3年没有使用字符串了。 我已经修改了我的帖子。 - Dennis
1
@Dennis:已撤销了负评并现在点赞了。顺便说一下,你也可以使用引用:void foo(string & s) { s = "dummy string"; }。现在没问题了。 - Nawaz
@Nawaz:谢谢。你不需要这样做,但我很感激。 - Dennis

0
代码片段调用了未定义的行为,因为从调用中创建的临时std::string在表达式结束时被销毁,但是指向已销毁对象的cc仍然在之后使用。

0

怎么样:

printf("%s", foo.c_str() );

或者更好的是,不要再使用字符指针了。


2
std::cout << foo() 怎么样? :D - Nawaz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接