I have a function in a library that takes in a char*
and modifies the data.
I tried to give it the c_str()
but c++ docs say it returns a const char*
.
What can I do other than newing a char array and copying it into that?
I have a function in a library that takes in a char*
and modifies the data.
I tried to give it the c_str()
but c++ docs say it returns a const char*
.
What can I do other than newing a char array and copying it into that?
You can use &str[0]
or &*str.begin()
as long as:
resize()
;str.size()
as the argument for the buffer size);\0
character you find, otherwise str.size()
will return the "preallocated size" instead of the "logical" string size.Notice: this is guaranteed to work in C++11 (where strings are guaranteed to be contiguous), but not in previous revisions of the standard; still, no implementation of the standard library that I know of ever did implement std::basic_string
with noncontiguous storage.
Still, if you want to go safe, use std::vector<char>
(guaranteed to be contiguous since C++03); initialize with whatever you want (you can copy its data from a string using the constructor that takes two iterators, adding a null character in the end), resize it as you would do with std::string
and copy it back to a string stopping at the first \0
character.
Nothing.
Because std::string
manages itself its contents, you can't have write access to the string's underlying data. That's undefined behavior.
However, creating and copying a char array is not hard:
std::string original("text");
std::vector<char> char_array(original.begin(), original.end());
char_array.push_back(0);
some_function(&char_array[0]);
If you know that the function will not modify beyond str.size()
you can obtain a pointer in one of different ways:
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() );
}
Note, this is guaranteed in C++11, but not in previous versions of the standard where it allowed for rope implementations (i.e. non-contiguous memory)
If your implementation will not try to increase the length of the string then:
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]);
Here's a class that will generate a temporary buffer and automatically copy it to the string when it's destroyed.
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;
};
And here's how you would use it:
// 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);
If you think you've seen this code before, it's because I copied it from a question I wrote: Guaranteed lifetime of temporary in C++?