This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
how to copy char * into a string and vice-versa
I have to pass a value into a method that required a char *
MyMethod(char * parameter)
{
// code
}
However, the parameter I need to feed it is currently a std::string. How do I convert the std::string to a char *?
std::string myStringParameter = //whatever
char * myCharParameter = //Convert here somehow
MyMethod(myCharParameter);
You are looking for the c_str() method:
char * myCharParameter = myStringParameter.c_str();
You might need to const_cast the return to get it into a char * instead of a const char *. Refrain from modifying the string though; it is the internal buffer of the std::string object. If you actually need to modify the string, you should use strncpy to copy it to another buffer:
char * myCharParameter = new char[myStringParameter.length() + 1];
strncpy(myCharParameter, myStringParameter.c_str(), myStringParameter.length() + 1);
// And later...
myStringParameter.assign(myCharParameter);
delete [] myCharParameter;
It depends on whether MyMethod actually changes the string that's passed in.
If the only thing you know about it is the signature, then you have to assume it could change the string, and copy it into a temporary buffer per #jdmichal's answer.
It's also possible that the developer of this API didn't know or care about const correctness. So the function takes in a non-const buffer even though it doesn't change it.
If that's the case you can get by with:
MyMethod(const_cast<char*>(myStringParameter.c_str());
In my career I have come across more than a few API's taking in non-const strings that should have been const.
If the function is actually going to modify the string, you'd better create a separate copy:
std::string str = // ...
char* cstr = strdup(str.c_str());
MyMethod(cstr);
// If you want to preserve the changes made:
// str = cstr;
free(cstr);
Related
I am trying to convert a char pointer to a string pointer but I am not sure if I am doing it correctly. I just wanted to post what I was trying and see if it was correct.
For context, I have a char * called ent->d_name and I need that to become a string *.
This is what I have been doing:
std::string arg = std::string(ent->d_name);
std::string * arg_p = &arg;
Command::_currentCommand->insertArgument(arg_p);
The insert command function takes a string pointer.
You could use
std::string *arg_p = new std::string(ent->d_name);
It will create a memory leak unless you delete each string after use, but apart from that it will work.
I have a number that I need to convert to a const char * (an API I'm using them requires const char * as input to many of its functions). The following works:
int num = 5;
std::string s = std::to_string(5);
const char * p = s.c_str();
as suggested by answers like those in how to convert from int to char*?, but it involves creating the seemingly unnecessary variable s, so I tried the following, but it doesn't work (p points to an empty string afterwards):
int num = 5;
const char * p = std::to_string(num).c_str();
Is there a clean way I can accomplish this? Why doesn't the second example work? The behavior is very similar to what happens if I made this obvious mistake:
const char * p;
{
std::string tempStr( "hi" );
p = tempStr.c_str( );
// p points to "hi" string.
}
// now p points to "" string.
Which makes me suspect that the issue std::to_string(num) immediately goes out of scope or something similar because it's not used to directly initialize anything.
std::string encapsulates managing dynamic memory (created with new[] and delete[]). Let's break it down.
const char * p = std::to_string(num).c_str();
Create a std::string (with a human-readable representation of num).
Get the new[]ly allocated const char* to the string.
Assign that value to p.
Destroy the std::string → delete[] the allocated const char*.
p points to... deallocated data
If you are using a pointer, the data that the pointer points to must exist throughout the lifetime of that pointer.
So, no, there is no way around this other than new[]ing a copy of the string, which you will have to explicitly delete[] later. And at that point, you've thrown the baby out with the bath and have no need to use std::string.
Create a string that lives at least as long as you want to refer to its internal data.
Just use std::string it does everything you want and everything that you would have to do manually if you don't use it.
When you need to pass a const char* to a const char* function simply use std::string::c_str() like this:
some_api_function(mystring.c_str()); // passes a const char*
What you need is a function which returns a char* which holds your value and can be used to manage its lifetime. The problematic version is broken because the char* points to memory which it does not manage.
For example:
std::unique_ptr<char[]> str(int32_t x)
{
std::unique_ptr<char[]> res(new char[12]);
snprintf(res.get(), 12, "%d", x);
return res;
}
Usestd::string everywhere and don't use const char* when not nessecary. They are basically the same thing. I use const char* only when I'm using a file-path.
Use std::string everywhere and your program should work.
This question already has answers here:
How to convert a std::string to const char* or char*
(11 answers)
Closed 9 years ago.
Currently I have a complex function that myself and our team are not wanting to refactor to utilize std::string and it takes a char* which is modified. How would I properly make a deep-copy of string::c_str() into a char*? I am not looking to modify the string's internally stored char*.
char *cstr = string.c_str();
fails because c_str() is const.
You can do it like this:
const std::string::size_type size = string.size();
char *buffer = new char[size + 1]; //we need extra char for NUL
memcpy(buffer, string.c_str(), size + 1);
Rather than modify the existing function, I'd just create an overload that acts as a wrapper. Assuming the existing function is ret_type f(char *), I'd write the overload something like:
ret_type f(std::string s) {
return f(&s[0]);
}
Note passing s by value instead of reference, minimizing the effort expended to get a copy of the string.
In theory, this isn't guaranteed to work (i.e., a string's buffer isn't guaranteed to be contiguous) until C++03. In reality, that guarantee was fairly easy for the committee to add primarily because nobody knew of an implementation of std::string that did anything else.
Likewise, it could theoretically be missing the NUL terminator. If you're concerned about that possibility you could use return f(const_cast<char *>(s.c_str())); instead, or add an s.push_back('\0'); before the return:
ret_type f(std::string s) {
s.push_back('\0');
return f(&s[0]);
}
The obvious solution is:
std::vector<char> tmp( string.begin(), string.end() );
tmp.push_back( '\0' );
function( &tmp[0] );
(I rather like Jerry Coffin's solution, however.)
Is it possible to pass the pointer of a std::string to a function which expects a **char? The function expects a **char in order to write a value to it.
Currently I am doing the following:
char *s1;
f(&s1);
std::string s2 = s1;
Is there no shorter way? It is obvious, that s2.c_str() does not work, since it returns const *char.
That's the appropriate way to handle that sort of function. You cannot pass in the std::string directly because, while you can convert it to a C string, it is laid out in memory differently and so the called function would not know where to put its result.
If possible, however, you should rewrite the function so it takes a std::string& or std::string * as an argument.
(Also, make sure you free() or delete[] the C string if appropriate. See the documentation for whatever f() is to determine if you need to do so.)
No, that's not possible. The function overwrites the pointer (s1) itself. You could pass in the data array from the string (&s2[0]) but that would only allow you to overwrite the currently reserved content space, not the pointer.
The function also somehow allocates memory for the string. You may need to clean that up too. If it had worked, how would it have been cleaned up?
You cannot - the string's char buffer is not writeable, and you shouldn't do it. You can always use an intermediate buffer:
const size_t n = s2.size();
char buf[n + 1];
buf[n] = 0;
std::copy(s2.begin(), s2.end(), buf);
f(&buf);
s2.assign(buf, n);
Yes, write a wrapper function/macro then just use it
One way you can pass your string into your function is to have your string
std::string name;
As the data-member of your object. And then, in the f() function create a string like you did, and pass it by reference like you showed
void f( const std::string & parameter_name ) {
name = parameter_name;
}
Now, to copy the string to char * so you can pass it into a function as a char reference:
From this link:
If you want to get a writable copy like str.c_str(), like char *, you can do that with this:
std::string str;
char * writable = new char[str.size() + 1];
std::copy(str.begin(), str.end(), writable);
writable[str.size()] = '\0'; // don't forget the terminating 0
// don't forget to free the string after finished using it
delete[] writable;
the above is not exception safe!
You can then pass the char * writable into your f() function by reference.
I have done a search in google and been told this is impossible as I can only get a static char * from a string, so I am looking for an alternative.
Here is the situation:
I have a .txt file that contains a list of other .txt files and some numbers, this is done so the program can be added to without recompilation. I use an ifstream to read the filenames into a string.
The function that they are required for is expecting a char * not a string and apparently this conversion is impossible.
I have access to this function but it calls another function with the char * so I think im stuck using a char *.
Does anyone know of a work around or another way of doing this?
In C++, I’d always do the following if a non-const char* is needed:
std::vector<char> buffer(str.length() + 1, '\0');
std::copy(str.begin(), str.end(), buffer.begin());
char* cstr = &buffer[0];
The first line creates a modifiable copy of our string that is guaranteed to reside in a contiguous memory block. The second line gets a pointer to the beginning of this buffer. Notice that the vector is one element bigger than the string to accomodate a null termination.
You can get a const char* to the string using c_str:
std::string str = "foo bar" ;
const char *ptr = str.c_str() ;
If you need just a char* you have to make a copy, e.g. doing:
char *cpy = new char[str.size()+1] ;
strcpy(cpy, str.c_str());
As previous posters have mentioned if the called function does in fact modify the string then you will need to copy it. However for future reference if you are simply dealing with an old c-style function that takes a char* but doesn't actually modfiy the argument, you can const-cast the result of the c_str() call.
void oldFn(char *c) { // doesn't modify c }
std::string tStr("asdf");
oldFn(const_cast< char* >(tStr.c_str());
There is c_str(); if you need a C compatible version of a std::string. See http://www.cppreference.com/wiki/string/basic_string/c_str
It's not static though but const. If your other function requires char* (without const) you can either cast away the constness (WARNING! Make sure the function doesn't modify the string) or create a local copy as codebolt suggested. Don't forget to delete the copy afterwards!
Can't you just pass the string as such to your function that takes a char*:
func(&string[0]);