我想将std :: string转换为char *或char []数据类型。
std::string str = "string";
char* chr = str;
结果为:“错误:无法将'std :: string'转换为'char'...”。
有什么方法可以做到这一点?
我想将std :: string转换为char *或char []数据类型。
std::string str = "string";
char* chr = str;
结果为:“错误:无法将'std :: string'转换为'char'...”。
有什么方法可以做到这一点?
Answers:
它不会自动转换(感谢上帝)。您必须使用该方法c_str()
来获取C字符串版本。
std::string str = "string";
const char *cstr = str.c_str();
注意它返回一个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;
或在现代C ++中:
std::vector<char> cstr(str.c_str(), str.c_str() + str.size() + 1);
vector
完全是作为动态数组的包装器而发明的,所以最好不要使用它似乎是一个错失的机会,并且最坏的情况是违反了C ++的精神。
std::string
用一个简短的代码示例解释了OP的错误(认为会自动转换的错误),然后解释了他应该使用的错误。展望未来,我还将解释使用此功能的一些副作用,其中之一是您可能无法编辑所返回的字符串c_str()
。您错误地将我的简短示例视为真正的解决问题的代码,事实并非如此。
std::vector<char>
)。
如果我需要c ++字符串内容的可变原始副本,则可以这样做:
std::string str = "string";
char* chr = strdup(str.c_str());
然后:
free(chr);
那么,为什么不像其他任何人一样摆弄std :: vector或new []?因为当我需要一个可变的C风格的原始char *字符串时,然后因为我想调用更改字符串的C代码,并且C代码使用free()释放内容并使用malloc()分配内容(strdup使用malloc)。因此,如果我将原始字符串传递给用C编写的某个函数X ,则可能会对它必须在堆上分配的参数有约束(例如,如果函数可能想在参数上调用realloc)。但是,几乎不可能期望分配有(某些用户定义的)new []的参数!
strdup
来自哪里。
(此答案仅适用于C ++ 98。)
请不要使用raw char*
。
std::string str = "string";
std::vector<char> chars(str.c_str(), str.c_str() + str.size() + 1u);
// use &chars[0] as a char*
vector<char>(str.c_str(), str.c_str() + str.size() + 1)
不将char指针分配给临时对象就可以说吗?
std::basic_string<>::c_str()
在string
更改或销毁之前一直有效。这也意味着只要string
不修改,它在后续调用中将返回相同的值。
vector
以这种方式使用不会产生速度或空间开销。而且,如果编写一个没有RAII机制的异常安全代码(即使用原始指针),则代码复杂度将比这种简单的单行代码高得多。
vector
具有大量开销和复杂性的神话。如果您的要求是拥有可变的 char数组,则实际上chars向量几乎是理想的C ++包装器。如果您的需求实际上只是要求使用const-char指针,则只需使用c_str()
就可以了。
如果只需要一个表示相同内容的C样式字符串:
char const* ca = str.c_str();
如果您想要带有新内容的C样式字符串,则一种方法(假设您在编译时不知道字符串大小)是动态分配:
char* ca = new char[str.size()+1];
std::copy(str.begin(), str.end(), ca);
ca[str.size()] = '\0';
以后不要忘记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);
std::string
不会隐式转换为这些类型,原因很简单,因为这样做通常是一种设计气味。确保您确实需要它。
如果您确实需要char*
,最好的方法可能是:
vector<char> v(str.begin(), str.end());
char* ca = &v[0]; // pointer to start of vector
&str.front(), &str.back()
(在C ++ 03中不存在)而不是更常见的str.begin()
and str.end()
?
str.begin()
,甚至std::begin(str)
,类迭代器?我不相信string
有像这样的连续记忆的义务vector
吗?
&back() + 1
,而不是&back()
为了完整起见,请不要忘记std::string::copy()
。
std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
str.copy(chrs, MAX);
std::string::copy()
不终止。如果需要确保在C字符串函数中使用NUL终止符,请执行以下操作:
std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
memset(chrs, '\0', MAX);
str.copy(chrs, MAX-1);
这是来自 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
if (str[str.length()-1] != 0) str.push_back(0)
OOP样式的转换
converter.hpp
class StringConverter {
public: static char * strToChar(std::string str);
};
converter.cpp
char * StringConverter::strToChar(std::string str)
{
return (char*)str.c_str();
}
用法
StringConverter::strToChar("converted string")
另外,您可以使用向量获取可写char *,如下所示;
//this handles memory manipulations and is more convenient
string str;
vector <char> writable (str.begin (), str.end) ;
writable .push_back ('\0');
char* cstring = &writable[0] //or &*writable.begin ()
//Goodluck
为了获得const char *
从一个std::string
使用c_str()
成员函数:
std::string str = "string";
const char* chr = str.c_str();
要从中获取非常量char *
,std::string
您可以使用data()
成员函数,该函数从C ++ 17开始返回非常量指针:
std::string str = "string";
char* chr = str.data();
对于较旧的语言版本,可以使用范围构造将字符串复制到向量中,从该向量中可以获取非const指针:
std::string str = "string";
std::vector<char> str_copy(str.c_str(), str.c_str() + str.size() + 1);
char* chr = str_copy.data();
但是请注意,这不会让您修改包含的字符串str
,只能以这种方式更改副本的数据。请注意,在此语言的较旧版本中使用它特别重要,c_str()
因为在那时std::string
,直到c_str()
被调用之前,都不能保证以null结尾。
c_str
完全避免这种疯狂。