How to copy the value of std::string to char[] properly? - c++

When I try to convert
char abc[65536];
std::string str; //= "abc";
std::copy(str.begin(), str.end(), abc); // abc = "abcÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ..."
When I to copy the value of str into abc, I'm getting ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ.. in addition.
How do I fix this please?

string has a constructor that accepts char*, so:
std::string str(abc);
edit: oh you changed the question. Your problem is with null termination.
str has 3 characters. copy copies these 3 characters. This means abc is not (yet) null-terminated. So you don't know where the end of the string is.
try
abc[str.length()] = 0;
to null-terminate it.
I would also recommend dynamically allocating this memory because 1. 64kb on the stack is a lot, and 2. you are setting yourself up for a hard-to-find disaster and/or security holes by making assumptions about a string size.
If you can use const char *, then consider just using str.c_str() to access the underlying array.

There is no need to use std::copy. Simply call the c_str() method on std::string.
char * cstr = new char [str.length()+1];
std::strcpy (cstr, str.c_str());

you can use strcpy(abc,str.c_str()), this will copy the string from str to abc.

Related

Modifying char array from string

I'd like to initialise a string and then modify the resultant char array. I did:
std::string str = "hello world";
const char* cstr = str.c_str();
// Modify contents of cstr
However, because cstr is const, I cannot modify the elements. If I remove const, I cannot use c_str().
What is the best way to achieve this?
Just modify str using the std::string member functions.
These functions include operator[].
Since C++11 (and assuming a compliant implementation), &str[0] is the pointer that you want.
The best and most straight forward way to do this is to just directly modify the std::string using its own operator[]:
str[0] = 'G'; // "Gello world"
If you truly need to copy the C-string, for whatever reason, then you have to create a new buffer, eg:
char* buffer = new char[str.length() + 1];
strcpy(buffer, str.c_str());
delete[] buffer;
The obvious flaw here is dynamic allocation. Just stick with modifying the std::string directly, it's what the class is written for, to make your life easier.

Can you copy data to `char*` pointer without allocating resource first?

I have seen an example here: http://www.cplusplus.com/reference/string/string/data/
...
std::string str = "Test string";
char* cstr = "Test string";
...
if ( memcmp (cstr, str.data(), str.length() ) == 0 )
std::cout << "str and cstr have the same content.\n";
Question> How can we directly copy data into the location where the pointer cstr pointed to without explicitly allocating space for it?
memcmp is comparing the content of memory pointed to by the two pointers. It does not copy anything.
[EDIT] The question was edited to add a concrete question. The answer is: you need the pointer to point to memory allocated one way or another if you want to copy data there.
How can we directly copy data into the location where the pointer cstr pointed to without explicitly allocating space for it?
You cannot, using an initialisation from a character string literal.
That memory will be placed in the static storage section of your program, and writing there is calling undefined behaviour (merely an exception in your particular compilers implementation).
lets assume that you used memcpy(cstr,x,...) instead of memcmp.
You use phrase 'without allocating resource first'. This really has no meaning.
For memcpy to work cstr must point at valid writable memory.
so the following work
char *cstr = new char[50];
char cstr[50];
char *cstr = malloc(50);
The following might work but shouldnt
char *cstr = "Foo"; // literal is not writable
This will not
char *cstsr = null_ptr;
char *cstrs; // you just might get lucky but very unlikely

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

How do I convert a string to a char* in c++?

I have an error in my program: "could not convert from string to char*". How do I perform this conversion?
If you can settle for a const char*, you just need to call the c_str() method on it:
const char *mycharp = mystring.c_str();
If you really need a modifiable char*, you will need to make a copy of the string's buffer. A vector is an ideal way of handling this for you:
std::vector<char> v(mystring.length() + 1);
std::strcpy(&v[0], mystring.c_str());
char* pc = &v[0];
Invoke str.c_str() to get a const char*:
const char *pch = str.c_str();
Note that the resulting const char* is only valid until str is changed or destroyed.
However, if you really need a non-const, you probably shouldn't use std::string, as it wasn't designed to allow changing its underlying data behind its back. That said, you can get a pointer to its data by invoking &str[0] or &*str.begin().
The ugliness of this should be considered a feature. In C++98, std::string isn't even required to store its data in a contiguous chunk of memory, so this might explode into your face. I think has changed, but I cannot even remember whether this was for C++03 or the upcoming next version of the standard, C++1x.
If you need to do this, consider using a std::vector<char> instead. You can access its data the same way: &v[0] or &*v.begin().
//assume you have an std::string, str.
char* cstr = new char[str.length() +1];
strcpy(cstr, str.c_str());
//eventually, remember to delete cstr
delete[] cstr;
Use the c_str() method on a string object to get a const char* pointer. Warning: The returned pointer is no longer valid if the string object is modified or destroyed.
Since you wanted to go from a string to a char* (ie, not a const char*) you can do this BUT BEWARE: there be dragons here:
string foo = "foo";
char* foo_c = &foo[0];
If you try to modify the contents of the string, you're well and truly on your own.
If const char* is good for you then use this: myString.c_str()
If you really need char* and know for sure that char* WILL NOT CHANGE then you can use this: const_cast<char*>(myString.c_str())
If char* may change then you need to copy the string into something else and use that instead. That something else may be std::vector, or new char[], it depends on your needs.
std::string::c_str() returns a c-string with the same contents as the string object.
std::string str("Hello");
const char* cstr = str.c_str();

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.