std :: string to char*

Mar*_*rio 305 c++ string char

我想将std :: string转换为char*char []数据类型.

std::string str = "string";
char* chr = str;
Run Code Online (Sandbox Code Playgroud)

结果:"错误:无法将'std :: string'转换为'char'...".

有什么方法可以做到这一点?

orl*_*rlp 627

它不会自动转换(感谢上帝).您必须使用该方法c_str()来获取C字符串版本.

std::string str = "string";
const char *cstr = str.c_str();
Run Code Online (Sandbox Code Playgroud)

注意它返回一个const char *; 您不能更改返回的C样式字符串c_str().如果你想处理它,你必须先复制它:

std::string str = "string";
char *cstr = new char[str.length() + 1];
strcpy(cstr, str.c_str());
// do stuff
delete [] cstr;
Run Code Online (Sandbox Code Playgroud)

或者在现代C++中:

std::vector<char> cstr(str.c_str(), str.c_str() + str.size() + 1);
Run Code Online (Sandbox Code Playgroud)

  • @ james-mcnellis,我选择了这个答案作为正确答案,因为它完全回答**我要求的答案......不多也不少.我没有问你认为我应该做什么,我没有要求你认为我在做什么的不同解决方案,我没有要求良好做法.你不知道我在做什么,我的代码将在哪里实现,以及在什么条件下.有些人应该学习阅读,理解问题并回答实际问题.不需要在这里炫耀. (110认同)
  • 首先,是的,答案是笨重的.首先我解释OP的错误(认为`std :: string`会自动转换)然后我用一个简短的代码示例解释他应该使用什么.向前思考我还解释了使用这个函数的一些副作用,其中一个是你不能编辑`c_str()`返回的字符串.你错误地将我的简短例子视为真正解决问题的代码,但事实并非如此. (21认同)
  • 答案是笨重,不优雅,非本地,使用原始数组,并需要注意异常安全.`vector`被发明为动态数组的包装器,所以不使用它似乎是错过了最好的机会,并且在最坏的情况下违反了C++的精神. (13认同)
  • 我低估了答案.这个答案确实没用,而且它被接受的事实是最不幸的.这个答案完全忽略了良好的C++编程实践和异常安全性,并且有很多优秀的解决方案,其中一些在这个问题的其他答案中给出(例如ildjarn给出的答案,它使用`std :: vector <char>`). (8认同)
  • @Kerrek SB:这是一个例子,会在实际代码中使用智能指针,或者更可能完全避免这种`c_str`疯狂. (3认同)
  • @Mario:足够公平.你所追求的确切事情并不总是很明显.在这种情况下,您似乎更倾向于在您的解决方案中添加手动内存管理(以及其固有的复杂性),这很好; 从一开始就不明显这是你的目标的一部分. (3认同)
  • @Deb你真的在引用[cplusplus.com](http://cplusplus.com/)吗?实际的 C++11 标准实际上定义了 `delete [ ]`,但例外的是 _“当 delete 关键字紧跟空方括号时,它应被解释为第二个选择。”_(第二个选择是 `删除原文中的[ ]`)。 (2认同)
  • 要在“现代”实现中获得实际的 char*,您可能需要这样做: std::vector&lt;char&gt; cvec(str.c_str(), str.c_str() + str.size() + 1); char *cstr = cvec.data(); (2认同)

bob*_*obo 139

更多细节在这里,并在这里,但你可以使用

string str = "some string" ;
char *cstr = &str[0];
Run Code Online (Sandbox Code Playgroud)

  • FWIW,在我的书中,这是对实际问题的唯一正确答案.std :: string本质上是可变的:听起来像修改字符串内容的人听起来似乎是魔鬼的工作似乎缺少这个事实. (14认同)
  • 请注意,这仅是C ++ 11。先前版本可能没有连续存储或缺少终止null (4认同)
  • 是的,这是正确的答案。愚蠢的是,鉴于使用频率,没有标准的方法可以做到这一点,例如msoft的锁缓冲区。 (2认同)

Nor*_*ame 38

如果我需要一个c ++的字符串内容的可变原始副本,那么我会这样做:

std::string str = "string";
char* chr = strdup(str.c_str());
Run Code Online (Sandbox Code Playgroud)

然后:

free(chr); 
Run Code Online (Sandbox Code Playgroud)

那么为什么我不像其他人那样摆弄std :: vector或new []?因为当我需要一个可变的C风格的原始字符串*时,因为我想调用更改字符串的C代码,C代码用free()释放内容并用malloc()分配(strdup使用malloc).因此,如果我将原始字符串传递给用C编写的某个函数X ,可能会对它的参数有一个约束,即它必须在堆上分配(例如,如果函数可能想要在参数上调用realloc).但它不太可能期望用(某些用户重新定义的)new []分配参数!


ild*_*arn 21

(这个答案仅适用于C++ 98.)

请不要使用原始的char*.

std::string str = "string";
std::vector<char> chars(str.c_str(), str.c_str() + str.size() + 1u);
// use &chars[0] as a char*
Run Code Online (Sandbox Code Playgroud)

  • "vector"具有大量的开销和复杂性,这是一个神话.如果你的要求是你有一个**mutable**char数组,那么实际上chars的向量几乎是理想的C++包装器.如果你的需求实际上只是调用一个const-char指针,那么只需使用`c_str()`就可以了. (7认同)
  • @ildjarn:实际上,[它基本上是](http://stackoverflow.com/a/2256521/560648). (3认同)
  • @friendzis:以这种方式使用`vector`没有速度或空间开销.如果有人在没有RAII机制的情况下编写**异常安全的**代码(即使用原始指针),代码复杂性将远远高于这个简单的单行代码. (2认同)

Lig*_*ica 15

  • 如果您只想要一个代表相同内容的C风格字符串:

    char const* ca = str.c_str();
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果你想要一个带有内容的C风格字符串,一种方法(假设你在编译时不知道字符串大小)是动态分配:

    char* ca = new char[str.size()+1];
    std::copy(str.begin(), str.end(), ca);
    ca[str.size()] = '\0';
    
    Run Code Online (Sandbox Code Playgroud)

    别忘了delete[]以后再说.

  • 如果你想要一个静态分配的,有限长度的数组:

    size_t const MAX = 80; // maximum number of chars
    char ca[MAX] = {};
    std::copy(str.begin(), (str.size() >= MAX ? str.begin() + MAX : str.end()), ca);
    
    Run Code Online (Sandbox Code Playgroud)

std::string不会隐式转换为这些类型,原因很简单,需要这样做通常是一种设计气味.确保你真的需要它.

如果你肯定需要char*,最好的方法可能是:

vector<char> v(str.begin(), str.end());
char* ca = &v[0]; // pointer to start of vector
Run Code Online (Sandbox Code Playgroud)

  • @Armen:谁知道?! (2认同)

hai*_*ear 10

作为对bobobobo答案的评论会更好,但我没有代表.它完成了同样的事情,但有更好的实践.

虽然其他的答案是有用的,如果你需要转换std::stringchar*明确无常量,const_cast是你的朋友.

std::string str = "string";
char* chr = const_cast<char*>(str.c_str());
Run Code Online (Sandbox Code Playgroud)

请注意,这不会为您提供数据的副本; 它会给你一个指向字符串的指针.因此,如果你修改了一个元素chr,你将修改str.


Fra*_*eux 7

为了获得const char *从一个std::string使用c_str()成员函数:

std::string str = "string";
const char* chr = str.c_str();
Run Code Online (Sandbox Code Playgroud)

要从char *an获取非常量,std::string您可以使用data()自 C++17 起返回非常量指针的成员函数:

std::string str = "string";
char* chr = str.data();
Run Code Online (Sandbox Code Playgroud)

对于旧版本的语言,您可以使用范围构造将字符串复制到可以从中获得非常量指针的向量中:

std::string str = "string";
std::vector<char> str_copy(str.c_str(), str.c_str() + str.size() + 1);
char* chr = str_copy.data();
Run Code Online (Sandbox Code Playgroud)

但请注意,这不会让您修改包含在 中的字符串str,只能以这种方式更改副本的数据。请注意,在旧版本的语言中使用c_str()这里特别重要,因为那时std::string不能保证c_str()在调用之前以空终止。


Mar*_*k B 6

假设你只需要一个C风格的字符串作为输入传递:

std::string str = "string";
const char* chr = str.c_str();
Run Code Online (Sandbox Code Playgroud)


Rob*_*b K 5

要严格迂腐,你不能"将std :: string转换为char*或char []数据类型."

正如其他答案所示,您可以将std :: string的内容复制到char数组,或者将const char*复制到std :: string的内容,以便您可以在"C style"中访问它.

如果您正在尝试更改std :: string的内容,则std :: string类型具有执行任何可能需要执行的操作的所有方法.

如果你试图将它传递给一个带有char*的函数,那就是std :: string :: c_str().


zan*_*ngw 5

这是一个更强大的版本 Protocol Buffer

char* string_as_array(string* str)
{
    return str->empty() ? NULL : &*str->begin();
}

// test codes
std::string mystr("you are here");
char* pstr = string_as_array(&mystr);
cout << pstr << endl; // you are here
Run Code Online (Sandbox Code Playgroud)


小智 5

OOP 风格的转换

转换器.hpp

class StringConverter {
    public: static char * strToChar(std::string str);
};
Run Code Online (Sandbox Code Playgroud)

转换器.cpp

char * StringConverter::strToChar(std::string str)
{
    return (char*)str.c_str();
}
Run Code Online (Sandbox Code Playgroud)

用法

StringConverter::strToChar("converted string")
Run Code Online (Sandbox Code Playgroud)