如何将std::string转换为const char*?

27

可能是重复问题:
如何将std::string转换为const char*或char*

void Foo::bar(const std::string& foobar) {
    // ...
    const char* foobar2 = (char*)foobar;
    // ...
}

这种方法不起作用,并且我在编译过程中会得到一个关于无效类型转换的错误。

是否有其他方法将 std::string 转换为 const char*


1
@GMan:有很多原因,其中主要原因是在C API中调用函数? - André Caron
2
@Gman 因为我需要将 foobar 变量传递给 UDT 的 inet_pton 函数,该函数仅接受 char* 类型的变量。 - Richard Knop
@GMan,许多函数仍然需要(char*),在C++中可以避免,但并非完全可避免。 - Aaron H.
5
@Andre @Aaron:我很少这样做。你真的认为一个初学者知道最好的做法吗?他是实际上想要 const char* 还是 char*?他应该使用 &foobar[0] 还是 std::vector<char>?如果他问目标而不是步骤,我们可以更好地回答这个问题。@Richard:我看到有一个函数接受 const char*void*,但没有任何关于 char* 的信息。因此,像我们所怀疑的那样,你只需要一个 const char*,因此使用 c_str 而不是 char*。(@And @Aar: 看看这个...) - GManNickG
3
@GMan:“我希望不会因为无法编写我应该编写的代码而被解雇。有什么建议吗?”询问目标,而非步骤;-p(你当然是对的)。 - Steve Jessop
显示剩余2条评论
4个回答

47

11

std::string::c_str()可以获取表示该字符串的字符数组的const char*指针(以null结尾)。

您不应该操纵此指针所指向的数据,因此如果需要对其进行操作,请复制数据。

双重编辑 - 以更C++的方式执行

既然在可能的情况下最好避免使用裸指针和数组,那么您还可以将数据存储到一个std::vector<char>中。

#include <string>
#include <vector>

int main()
{
    std::string str = "Hello";
    std::vector<char> cvec(str.begin(), str.end()); 

    // do stuff
}

编辑此内容更像是使用原始指针并显式分配内存的C语言

#include <string>
#include <cstring>

int main()
{
    std::string str = "Hello";
    char *cptr = new char[str.size()+1]; // +1 to account for \0 byte
    std::strncpy(cptr, str.c_str(), str.size());

    // do stuff...
    delete [] cptr;
}

3
使用std::vector,永远不要使用new T[] - GManNickG
@GMan - 谢谢 - 当问题涉及指针时,我总是默认采用非常C风格的行为,尽管在C++领域中,我知道我应该先使用C++级别的内容进行教学。 - wkl
为什么要使用 strncpy 而不是 strcpy - i486
这是strcpy的安全版本。它接受长度作为参数,因此不会超出数组的最大索引。 - eiran

4
您会得到很多关于str.c_str()的有点不正确的答案。尽管c_str()确实有用,请记住,它不会将字符串实际转换为char*,而是将字符串内容作为const char*返回,这是一个很大的区别! 重要的是,您从c_str()获得的指针仅在给定字符串对象存在的时间内有效。因此,下面的做法是非常错误的:
class Something {
    const char* name;
public:
    Something(const std::string& pname) {
        this->name = pname.c_str(); /* wrong! the pointer will go wrong as the object from the parameter ceases to exist */
    }
};

如果你想要转换一个字符串,也就是创建一个新值,该值将独立于原始的std::string,那么你需要这样做:

char* convert(const std::string& str) {
    char* result = new char[str.length()+1];
    strcpy(result,str.c_str());
    return result;
}

但在大多数情况下,c_str()已经足够了。只需尝试按对象的生命周期来思考。


2
应该是 str.length()+1,因为长度不包括空字节。 - wkl
2
使用 std::vector,永远不要使用 new T[] - GManNickG
4
@Kos: 你可以尽情地写诗般的代码,但没有理由使用new T[]来代替std::vector<T>,或者scoped_ptr/unique_ptr<T[]>。除非你想编写不安全的异常处理、资源管理不当等糟糕的代码......C++虽然可以是低级的,但这并不意味着你可以、必须或者能够编写差劲的代码而不受惩罚。 - GManNickG
@GManNickG 你好,来自2017年的我向你问候!现在我完全同意你的观点,裸指针真的很让人头疼。希望我的回答前几句话还能挽救一下。 - Kos
@Kos:哈哈,不错。 :) - GManNickG
显示剩余4条评论

3
const char* foobar2 = foobar.c_str();

请注意const关键字,否则您需要将其复制到char缓冲区中。

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