How can I convert an std::string to a char* or a const char*?
How can I convert an std::string to a char* or a const char*?
If you just want to pass a std::string to a function that needs const char* you can use
std::string str;
const char * c = str.c_str();
If you want to get a writable copy, 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;
Edit: Notice that the above is not exception safe. If anything between the new call and the delete call throws, you will leak memory, as nothing will call delete for you automatically. There are two immediate ways to solve this.
boost::scoped_array will delete the memory for you upon going out of scope:
std::string str;
boost::scoped_array<char> writable(new char[str.size() + 1]);
std::copy(str.begin(), str.end(), writable.get());
writable[str.size()] = '\0'; // don't forget the terminating 0
// get the char* using writable.get()
// memory is automatically freed if the smart pointer goes
// out of scope
This is the standard way (does not require any external library). You use std::vector, which completely manages the memory for you.
std::string str;
std::vector<char> writable(str.begin(), str.end());
writable.push_back('\0');
// get the char* using &writable[0] or &*writable.begin()
Use the .c_str() method for const char *.
You can use &mystring[0] to get a char * pointer, but there are a couple of gotcha's: you won't necessarily get a zero terminated string, and you won't be able to change the string's size. You especially have to be careful not to add characters past the end of the string or you'll get a buffer overrun (and probable crash).
There was no guarantee that all of the characters would be part of the same contiguous buffer until C++11, but in practice all known implementations of std::string worked that way anyway; see Does “&s[0]” point to contiguous characters in a std::string?.
Note that many string member functions will reallocate the internal buffer and invalidate any pointers you might have saved. Best to use them immediately and then discard.
Converting from c++ std string to C style string is really easy now.
For that we have string::copy function which will easily convert std string to C style string. reference
string::copy functions parameters serially
Another important thing,
This function does not append a null character at the end of operation. So, we need to put it manually.
Code exam are in below -
// char string
char chText[20];
// c++ string
string text = "I am a Programmer";
// conversion from c++ string to char string
// this function does not append a null character at the end of operation
text.copy(chText, text.size(), 0);
// we need to put it manually
chText[text.size()] = '\0';
// below statement prints "I am a Programmer"
cout << chText << endl;
Vice Versa, Converting from C style string to C++ std string is lot more easier
There is three ways we can convert from C style string to C++ std string
First one is using constructor,
char chText[20] = "I am a Programmer";
// using constructor
string text(chText);
Second one is using string::assign method
// char string
char chText[20] = "I am a Programmer";
// c++ string
string text;
// convertion from char string to c++ string
// using assign function
text.assign(chText);
Third one is assignment operator(=), in which string class uses operator overloading
// char string
char chText[20] = "I am a Programmer";
// c++ string
// convertion from char string to c++ string using assignment operator overloading
string text = chText;
third one can be also write like below -
// char string
char chText[20] = "I am a Programmer";
// c++ string
string text;
// convertion from char string to c++ string
text = chText;
let's say, string str="stack";
1)converting string to char*
char* s_rw=&str[0];
The above char*(i.e., s_rw) is readable and writeable and points to the base address of the string which needs to be converted to char*
2)Converting string to const char*
const char* s_r=&str[0];
The above const char* (i.e., s_r) is readable but not writeable and points to the base address of the string.
This is especially useful when passing the underlying char* buffer of a std::string to C calls which expect and write to a char* buffer. This way you get the best of both worlds!: the niceties of the C++ std::string and the usability of it directly with C libraries you are calling from C++.
std::string as a C-style read/writable char* or read-only null-terminated const char*How can I convert a
std::stringto achar*or aconst char*?
Despite being a really old and highly-upvoted question, the information I'm about to cover isn't already well-covered, if covered at all, so this is a necessary addition, in particular the part about needing to pre-allocate the underlying C-string using the .resize() method if you'd like to use it as a writable buffer.
All of the usages below require C++11 or later, except for the char* data() call, which requires C++17 or later.
To run and test all example code below, and more, see and run my string__use_std_string_as_a_c_str_buffer.cpp file in my eRCaGuy_hello_world repo.
std::string as a read/writable char*To use a C++ std::string as a C-style writable char* buffer, you MUST first pre-allocate the string's internal buffer to change its .size() by using .resize(). Note that using .reserve() to increase only the .capacity() is NOT sufficient! The cppreference.com community wiki page for std::string::operator[] correctly states:
If
pos > size(), the behavior is undefined.
The resize() method is what changes the size, not the reserve() method, which changes only the capacity().
Ex:
#include <cstring> // `strcpy()`
#include <iostream>
#include <string>
constexpr size_t BUFFER_SIZE = 100;
std::string str;
str.resize(BUFFER_SIZE); // pre-allocate the underlying buffer
// check the size
std::cout << "str.size() = " << str.size() << "\n";
For all examples below, assume you have these C-strings:
constexpr char cstr1[] = "abcde ";
constexpr char cstr2[] = "fghijk";
Once you have pre-allocated an underlying buffer which is sufficiently large with resize(), you can then access the underlying buffer as
a char* in at least 3 ways:
operator[] to obtain a char, followed by obtaining its address with &. Ex:
char* c_str;
c_str = &str[0];
c_str = &str[5];
// etc.
// Write these 2 C-strings into a `std::string`'s underlying buffer
strcpy(&str[0], cstr1);
strcpy(&str[sizeof(cstr1) - 1], cstr2); // `- 1` to overwrite the first
// null terminator
// print the string
std::cout << str << "\n"; // output: `abcde fghijk`
What if you have a pointer to a std::string? If you have a ptr to a std::string, it must be dereferenced first with *pstr before you can index into it as an array with the operator[] as &(*pstr)[0], so the syntax above becomes a little more awkward. Here is a full example:
std::string str2;
std::string* pstr = &str2;
pstr->resize(BUFFER_SIZE);
c_str = &(*pstr)[0]; // <=== dereference the ptr 1st before indexing into it
// Or, to make the order of precedence
// (https://en.cppreference.com/w/cpp/language/operator_precedence) really
// obvious, you can optionally add extra parenthesis like this:
c_str = &((*pstr)[0]);
.data() method to obtain a char* directly. Ex:
char* c_str;
c_str = str.data();
c_str = str.data() + 5;
// etc.
// Write these 2 C-strings into the `std::string`'s underlying buffer
strcpy(str.data(), cstr1);
strcpy(str.data() + (sizeof(cstr1) - 1), cstr2); // `- 1` to overwrite the
// first null terminator
// print the string
std::cout << str << "\n"; // output: `abcde fghijk`
.begin() method to obtain an iterator to the first char, and then use the iterator's operator*() dereference method to obtain the iterator's char value_type, and then take the address of that to obtain a char*. Ex:
char* c_str;
c_str = &(*str.begin());
c_str = &(*str.begin()) + 5;
// etc.
// Write these 2 C-strings into the `std::string`'s underlying buffer
strcpy(&(*str.begin()), cstr1);
strcpy(&(*str.begin()) + (sizeof(cstr1) - 1), cstr2); // `- 1` to overwrite
// the first null
// terminator
// print the string
std::cout << str << "\n"; // output: `abcde fghijk`
Something important to be aware of is that when you call str.resize(100), it reserves at least 100 bytes for the underlying string, sets the size() of the string to 100, and initializes all 100 of those chars to char()--AKA: the default value initialization value for char (see my question here), which is the binary zero null-terminator, '\0'. Therefore, whenever you call str.size() it will return 100 even if the string simply has "hello" in it followed by 95 null-terminators, or zeros. To get the length, or number of non-null-terminators in the string, you'll have to resort to the C function strlen(), like this:
std::cout << strlen(str.c_str()) << "\n"; // prints `12` in the examples above
// instead of:
std::cout << str.size() << "\n"; // prints `100` in the examples above
std::string as a read-only, null-terminated const char*To obtain a readable null-terminated const char* from a std::string, use the .c_str() method. It returns a C-style string that is guaranteed to be null-terminated. Note that the .data() method is NOT the same thing, as it is NOT guaranteed to be null-terminated!
Example:
std::string str = "hello world";
printf("%s\n", str.c_str());
(questions on Stack Overflow)
(my content)
(from the cppreference.com community wiki)
https://en.cppreference.com/w/cpp/string/basic_string:
The elements of a basic_string are stored contiguously, that is, for a basic_string s, &*(s.begin () + n) == &*s.begin() + n for any n in [0, s.size()), or, equivalently, a pointer to s[0] can be passed to functions that expect a pointer to the first element of a null-terminated (since C++11)CharT[] array.
https://en.cppreference.com/w/cpp/string/basic_string/operator_at
Returns a reference to the character at specified location pos. No bounds checking is performed. If pos > size(), the behavior is undefined.
https://en.cppreference.com/w/cpp/string/basic_string/resize
https://en.cppreference.com/w/cpp/string/basic_string/reserve