我想将一个 std::string 转换为 char* 或 char[] 数据类型。
std::string str = "string";
char* chr = str;
结果是:“错误:无法将'std::string'转换为'char' ...”。
有哪些可用的方法可以解决这个问题?
它不会自动转换(谢天谢地)。你需要使用方法 c_str()
来获取 C 字符串版本。
std::string str = "string";
const char *cstr = str.c_str();
请注意,它返回一个const char *
;你不允许更改c_str()
返回的C风格字符串。如果你想对它进行处理,你需要先复制它:
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);
c_str
的混乱。 - orlpvector
恰好是专门作为动态数组的包装器而被发明出来的,所以不使用它似乎最多只能算是错失良机,最糟糕的情况则违背了C++的精神。 - Kerrek SBstd::string
会自动转换),然后提供了应该使用的内容,并附上了一个简短的代码示例。同时,我还预测了使用此函数可能产生的一些副作用,其中之一是您可能无法编辑 c_str()
返回的字符串。您错误地将我的简短示例视为实际的问题解决代码,但它不是。 - orlpstd::vector<char>
的答案)。 - James McNellisstring str = "some string" ;
char *cstr = &str[0];
从 C++11 开始,您还可以使用 str.data()
成员函数,它返回 char *
string str = "some string" ;
char *cstr = str.data();
char *cstr = nullptr;
{
string str = "some string" ;
cstr = &str[0];
}
std::cout<
- Cosmo如果我需要一个可变的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
是从哪里来的。 - L. F.(本答案仅适用于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*
vector<char>(str.c_str(), str.c_str() + str.size() + 1)
,而不将char指针分配给临时变量? - Kerrek SBchar * chars =&str [0];
而不是创建一个std :: vector
作为中介吗? - bobobobo如果您只需要一个表示相同内容的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()
和 str.end()
? - Armen Tsirunyanstr.begin()
怎么样?甚至是std::begin(str)
,类似于迭代器?我不认为string
有像vector
一样必须在连续内存中的义务,难道有吗? - xtofl&back() + 1
而不是&back()
。 - Armen Tsirunyanvector<char> v(str.begin(), str.end())
更加简洁明了,而且更为重要的是它更加短小精悍。 - Christian Rau这应该作为对bobobobo的答案的评论,但我没有足够的声望来这样做。它可以实现相同的效果,但是使用更好的实践。
虽然其他答案也有用,但如果您需要明确将std ::string
转换为未带const的char*
,那么const_cast
就是您的朋友。
std::string str = "string";
char* chr = const_cast<char*>(str.c_str());
请注意,这将不会给您数据的副本;它将为您提供指向字符串的指针。因此,如果您修改了chr
的元素,则会修改str
。
const char*
而不是 char *
,可能有很好的理由。const
表示“不要修改这个对象”。当你使用 const_cast
时,你在说“我知道得更好,我真的可以修改这个对象。”或者你在说“我不会修改这个对象,我只需要通过这个函数传递它,但这个函数没有声明它的输入是 const
的。”虽然似乎安全地丢弃 C 字符串的 const
特性,因为我们知道它是可变数据,但你真的不应该这样做。尽可能避免使用 const_cast
。 - bobobobostd::string
获取一个 const char *
,可以使用 c_str()
成员函数:std::string str = "string";
const char* chr = str.c_str();
如果要从 std::string
中获取非常量 char *
,可以使用自 C++17 以来返回非常量指针的 data()
成员函数:
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()
之前不能保证以空字符结尾。
std::string str = "string";
const char* chr = str.c_str();
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)
- GaspardP