Converting a char * to string * - c++

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.

Related

Convert to std::string and get const char * in one line

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.

Pass std::string to a function f(**char)

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.

Convert std::string to char * alternative

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]);

C++ char * to string [duplicate]

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);

How to assign a string to char *pw in c++

How to assign a string to a char* (char pointer) in C++?
char *pw = some string
For constant initialization you can simply use
const char *pw = "mypassword";
if the string is stored in a variable, and you need to make a copy of the string then you can use strcpy() function
char *pw = new char(strlen(myvariable) + 1);
strcpy(pw, myvariable);
// use of pw
delete [] pw; // do not forget to free allocated memory
If you just want to assign a string literal to pw, you can do it like char *pw = "Hello world";.
If you have a C++ std::string object, the value of which you want to assign to pw, you can do it like char *pw = some_string.c_str(). However, the value that pw points to will only be valid for the life time of some_string.
If you mean a std::string, you can get a pointer to a C-style string from it, by calling c_str. But the pointer needs to be const.
const char *pw = astr.c_str();
If pw points to a buffer you've previously allocated, you might instead want to copy the contents of a string into that buffer:
astr.copy(pw, lengthOfBuffer);
If you're starting with a string literal, it's already a pointer:
const char *pw = "Hello, world".
Notice the const again - string literals should not be modified, as they are compiled into your program.
But you'll have a better time generally if you use std::string everywhere:
std::string astr("Hello, world");
By the way, you need to include the right header:
#include <string>
I think you may want to do this:
using namespace std;
string someString;
geline(cin,someString);
char *pw = strdup(someString.c_str());
But consider doing it another way. Check out http://tiswww.case.edu/php/chet/readline/rltop.html (GNU Readline library). I don't know details about it, just heard about it. Others may have more detailed or other tips for reading passwords from standard input.
If you only want to use it for a single call for something you do not need to copy the contents of someString, you may use someString.c_str() directly if it is required as const char *.
You have to use free on pw some time later,
String must be enclosed in double quotes like :
char *pStr = "stackoverflow";
It will store this string literal in the read only memory of the program.
And later on modification to it may cause UB.