我在库中有一个函数,它接收char*
并修改数据。
我试图给它c_str()
,但c ++文档说它返回const char*
。
除了新建一个char数组并将其复制到其中之外,我还能做些什么呢?
答案 0 :(得分:14)
您可以使用&str[0]
或&*str.begin()
,只要:
resize()
; str.size()
作为缓冲区大小的参数); \0
字符处显式修剪字符串,否则str.size()
将返回“预分配大小”而不是“逻辑”字符串大小。 注意: 这可以保证在C ++ 11中工作(其中字符串保证是连续的),但不能在以前的标准版本中使用;仍然没有实现我所知道的标准库,它实现了std::basic_string
非连续存储。
但是,如果你想要安全,请使用std::vector<char>
(保证自C ++ 03以来是连续的);用你想要的任何东西初始化(你可以使用带有两个迭代器的构造函数从字符串中复制它的数据,最后添加一个空字符),像调用std::string
那样调整它的大小并将其复制回字符串停在第一个\0
字符。
答案 1 :(得分:10)
没有
由于std::string
管理自己的内容,因此您无法对字符串的基础数据进行写访问。这是未定义的行为。
但是,创建和复制char数组并不难:
std::string original("text");
std::vector<char> char_array(original.begin(), original.end());
char_array.push_back(0);
some_function(&char_array[0]);
答案 2 :(得分:3)
如果您知道该函数不会在str.size()
之后修改,您可以通过不同的方式获取指针:
void f( char* p, size_t s ); // update s characters in p
int main() {
std::string s=...;
f( &s[0], s.size() );
f( &s.front(), s.size() );
}
请注意,这在C ++ 11中是有保证的,但在标准的先前版本中不允许 rope 实现(即非连续内存)
答案 3 :(得分:2)
如果你的实现不会尝试增加字符串的长度,那么:
C ++ 11:
std::string data = "This is my string.";
func(&*data.begin());
C ++ 03:
std::string data = "This is my string.";
std::vector<char> arr(data.begin(), data.end());
func(&arr[0]);
答案 4 :(得分:0)
这是一个类,它将生成一个临时缓冲区,并在它被销毁时自动将其复制到字符串中。
class StringBuffer
{
public:
StringBuffer(std::string & str) : m_str(str)
{
m_buffer.push_back(0);
}
~StringBuffer()
{
m_str = &m_buffer[0];
}
char * Size(int maxlength)
{
m_buffer.resize(maxlength + 1, 0);
return &m_buffer[0];
}
private:
std::string & m_str;
std::vector<char> m_buffer;
};
以下是您将如何使用它:
// this is from a crusty old API that can't be changed
void GetString(char * str, int maxlength);
std::string mystring;
GetString(StringBuffer(mystring).Size(MAXLEN), MAXLEN);
如果您认为之前已经看过这段代码,那是因为我从我写的问题中复制了它:Guaranteed lifetime of temporary in C++?