6

I usually find some functions with char* as its parameter.But I heard that std::string is more recommended in C++. How can I use a std::string object with functions taking char*s as parameters? Till now I have known the c_str(), but it doesn't work when the content of string should be modified.

3 Answers 3

6

For that purpose, you use std::string::data(). Returns a pointer to the internal data. Be careful not to free this memory or anything like that as this memory is managed by the string object.

Sign up to request clarification or add additional context in comments.

4 Comments

@idclev463035818 Some people say if you read beyond the null terminator, you'll be able to find each and every internet page there. :)
Thank you very much!
@Evg At the very least, nobody can say you won't find them there.
@Evg don't try to make fun of me, I have seen the internet and there are no strings attached :P
6

You can use the address of the first element after C++11 like this:

void some_c_function(char* s, int n); // ... std::string s = "some text"; some_c_function(&s[0], s.size()); 

Before C++11 there was no guarantee that the internal string was stored in a contiguous buffer or that it would be null terminated. In those cases making a copy of the string was the only safe option.

After C++17 (the current standard) you can use this:

some_c_function(s.data(), s.size()); 

In C++17 a non-const return value of std::string::data() was added in addition to the const version.

5 Comments

Presumably, the some_c_function will leave a '\0' terminated C-style string in the "buffer". The string needs to be resized afterwards, because it's size includes the '\0' and the rest of the trailing fallow "buffer".
@Eljay That could be so. But I don't want to second guess what the C function might do. Some legacy functions don' t modify strings they are just lax about using const. Also a lot of functions simply fill the string buffer and return the length filled. There could be an alternative end value (like '\n') etc...
what was different before c++11?
Aye, good point. I can think of several different ways a buffer could be used. It may be used as a binary buffer, so a '\0' may just be data (as used for input only, for input/output, or output buffer only). It may be just a C-style string for input (so a size should be irrelevant). It may be a C-style string output buffer, so a size-as-a-buffer-limit to prevent overrun would be very important. All depends on the API.
"Before C++11 there was no guarantee that the internal string was stored in a contiguous buffer or that it would be null terminated." - true, but in practice MOST implementations actually were, because it kept the implementation of c_str() simple. And so when C++11 changed the requirements to require contiguous-ness and null termination, most implementations were already in compliance (that is probably one of the reasons why C++11 made the change in the first place, to make the common practice standardized).
4

Since C++17 std::string::data() returns a pointer to the underlying char array that does allow to modify the contents of the string. However, as usual with strings, you may not write beyond its end. From cppreference:

Modifying the past-the-end null terminator stored at data()+size() to any value other than CharT() has undefined behavior.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.