This question already has answers here:
std::string to char*
(18 answers)
Closed 8 years ago.
I have a problem to output a string. Can you help me?
In the following, const char * i and const char ** o are given.
The statement, "*o = temp" produces an error, saying that "std::string" and "const char *" do not fit. What is the problem?
int mytask(const char * i, const char ** o)
{
std::string temp = std::string("mytask:") + i;
*o = temp; //How to modify?
return (0);
}
First of all you are trying to assign a local char pointer and use it in calling function, where it have already been destroyed. So instead you should do this. Assuming memory is allocated for o:
strcpy(*o,temp.c_str());
*o=temp means you are making the o point to a pointer that points to a std::string however o is a pointer that points to a char (or sequence of chars). This is not allowed. The other way around works: temp=*o because the std::string object defines what happens when you assign a char* to it (copy the null terminated string into the object). If you absolutely must copy from temp into the char* pointed to by o*. use strcpy() and std::string.c_str()
strcpy(*o,temp.c_str())
In C++, it's unusual to pass raw pointers around in this manner.
Returning 0 doesn't achieve much either.
I'd expect to see something like this:
std::string mytask(std::string const& i)
{
return "mytask:" + i;
}
int main()
{
std::string const number { '1' };
std::string const ret { mytask(number) };
}
The statement
strcpy(*o,temp.c_str());
didn't work. I resolved this problem by
*o = temp.c_srt();
instead. Thanks all anyway.
Related
This question already has answers here:
returning a pointer to a literal (or constant) character array (string)?
(3 answers)
Closed 3 years ago.
I have a legacy code snippet that looks like:
const char *GetStr() const {
return ("");
}
I am wondering whether this is a risky code as instead of returning a global character pointer, returning a local string literal?
For example, perhaps, the following code snippet is better.
const char *NullStr = "";
const char *GetStr() const {
return NullStr; // instead of ""
}
What could be pros/cons?
Even the following implementation could be better:
const char *GetStr() const {
static const char * lNullStr = "";
return lNullStr;
}
Your first snippet is not strictly portable.
An alternative, which is, is:
const char *GetStr() const {
static const char* s = "";
return s;
}
and also has the benefit that s is contained within the function.
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:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 9 years ago.
I have the following function in c++
char* Test::convertToSHA(const char* cc) {
const char* salt ="sh$^$##!&7hbfvatfacv####bagg=shjgvshvcbschj";
time_t currentTime;
time(¤tTime);
CCString startTimeString;
startTimeString.createWithFormat("%d", currentTime);
std::string s = cc;
s += startTimeString.getCString();
s += salt;
char *str = new char[strlen(s.c_str()) + 1];
int length=strlen(str);
unsigned char hash[length*2];
char hexstring[41];
sha1::calc(str,length,hash);
sha1::toHexString(hash, hexstring);
return hexstring;
}
And in the call i use
char* output=NULL;
output= Test::convertToSHA("hello");
This is causing my code to crash. Is there a problem with me returning a string ? How can i return from this function ?
You can never return a local pointer in C or C++. Instead, either pass the pointer as a parameter:
void Test::convertToSHA(const char* cc, const char* hexstring) {
//no change to body
//no return statement needed
}
//then when calling the function:
char hexstring[41];
convertToSHA(cc, hexstring);
//hexstring has been modified
Or just use std::string instead. Use the c_str() if you need to convert to a c-style string (you still can't return the pointer, though).
I'm assuming you're using this library. I find it odd that it claims to be written in C++ but doesn't take advantage of C++ idioms. The function modifies the pointer, and doesn't return anything, so you do need a local variable. Lucky for you, std::strings will happily accept a char [] argument.
std::string Test::convertToSHA(const char* cc) {
// ...
char hexstring[41];
sha1::calc(str,length,hash);
sha1::toHexString(hash, hexstring);
std::string ret(hexstring);
return ret;
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Convert std::string to const char* or char*
void Foo::bar(const std::string& foobar) {
// ...
const char* foobar2 = (char*)foobar;
// ...
}
That does not work and I get an error during compilation about invalid casting.
Is there some other way to convert std::string to const char*?
Use foobar.c_str().
You might find this link useful: http://www.cppreference.com/wiki/string/start
std::string::c_str() gets you a const char* pointer to a character array that represents the string (null-terminated).
You should not manipulate the data this pointer points to, so if you need to do that, copy the data.
Double edit - doing it in a more C++ fashion
Since it is nicer to avoid the use of raw pointers and arrays where possible, you can also get the data into an std::vector<char>
#include <string>
#include <vector>
int main()
{
std::string str = "Hello";
std::vector<char> cvec(str.begin(), str.end());
// do stuff
}
edit this is more like C since it uses raw pointers and explicitly allocates mem
#include <string>
#include <cstring>
int main()
{
std::string str = "Hello";
char *cptr = new char[str.size()+1]; // +1 to account for \0 byte
std::strncpy(cptr, str.c_str(), str.size());
// do stuff...
delete [] cptr;
}
You're going to get a lot of kinda incorrect answers about str.c_str() here. :) While c_str() is indeed useful, please keep in mind that this will not actually convert the string into a char*, but rather return the contents of the string as a const char*. And this is a big difference!
What's important here is that the pointer you obtain from c_str() is valid only as long as the given string object exists. So this would be terribly wrong:
class Something {
const char* name;
public:
Something(const std::string& pname) {
this->name = pname.c_str(); /* wrong! the pointer will go wrong as the object from the parameter ceases to exist */
}
};
So if you want to convert, as in: create a new value which will be independent of the original std::string, then you'll want to do something like this:
char* convert(const std::string& str) {
char* result = new char[str.length()+1];
strcpy(result,str.c_str());
return result;
}
But still c_str() will be quite enough for you in most cases. Just try to think in terms of objects' time of life.
const char* foobar2 = foobar.c_str();
Notice the const.
Otherwise you have to copy it to a char buffer.
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);