user1598585
user1598585

Reputation:

std::string to char*

I want to convert a std::string into a char* or char[] data type.

std::string str = "string";
char* chr = str;

Results in: “error: cannot convert ‘std::string’ to ‘char’ ...”.

What methods are there available to do this?

Upvotes: 486

Views: 1278257

Answers (18)

orlp
orlp

Reputation: 117781

It won't automatically convert (thank god). You'll have to use the method c_str() to get the C string version.

std::string str = "string";
const char *cstr = str.c_str();

.c_str() returns a const char *. If you want a non-const char *, use .data():

std::string str = "string";
char *cstr = str.data();

Some other options:

  • Copying the characters into a vector:

    std::vector<char> cstr(str.c_str(), str.c_str() + str.size() + 1);
    

    Then cstr.data() will give you the pointer.

    This version copies the terminating \0. If you don't want it, remove + 1 or do std::vector<char> cstr(str.begin(), str.end());.

  • Copying into a manually allocated array: (should normally be avoided, as manual memory management is easy to get wrong)

    std::string str = "string";
    char *cstr = new char[str.size() + 1];
    std::strcpy(cstr, str.c_str());
    // do stuff
    delete [] cstr;
    

Upvotes: 854

bobobobo
bobobobo

Reputation: 67306

More details here, and here but you can use

string str = "some string" ;
char *cstr = &str[0];

As of C++11, you can also use the str.data() member function, which returns char *

string str = "some string" ;
char *cstr = str.data();

Upvotes: 251

Felix Feng
Felix Feng

Reputation: 7

No body ever mentioned sprintf?

std::string s;
char * c;
sprintf(c, "%s", s.c_str());

Upvotes: -1

Fran&#231;ois Andrieux
Fran&#231;ois Andrieux

Reputation: 29032

To obtain a const char * from an std::string use the c_str() member function :

std::string str = "string";
const char* chr = str.c_str();

To obtain a non-const char * from an std::string you can use the data() member function which returns a non-const pointer since C++17 :

std::string str = "string";
char* chr = str.data();

For older versions of the language, you can use range construction to copy the string into a vector from which a non-const pointer can be obtained :

std::string str = "string";
std::vector<char> str_copy(str.c_str(), str.c_str() + str.size() + 1);
char* chr = str_copy.data();

But beware that this won't let you modify the string contained in str, only the copy's data can be changed this way. Note that it's specially important in older versions of the language to use c_str() here because back then std::string wasn't guaranteed to be null terminated until c_str() was called.

Upvotes: 9

Patryk Merchelski
Patryk Merchelski

Reputation: 86

Conversion in OOP style

converter.hpp

class StringConverter {
    public: static char * strToChar(std::string str);
};

converter.cpp

char * StringConverter::strToChar(std::string str)
{
    return (char*)str.c_str();
}

usage

StringConverter::strToChar("converted string")

Upvotes: 5

hairlessbear
hairlessbear

Reputation: 341

This would be better as a comment on bobobobo's answer, but I don't have the rep for that. It accomplishes the same thing but with better practices.

Although the other answers are useful, if you ever need to convert std::string to char* explicitly without const, const_cast is your friend.

std::string str = "string";
char* chr = const_cast<char*>(str.c_str());

Note that this will not give you a copy of the data; it will give you a pointer to the string. Thus, if you modify an element of chr, you'll modify str.

Upvotes: 13

ildjarn
ildjarn

Reputation: 62995

(This answer applies to C++98 only.)

Please, don't use a raw char*.

std::string str = "string";
std::vector<char> chars(str.c_str(), str.c_str() + str.size() + 1u);
// use &chars[0] as a char*

Upvotes: 25

Enhex
Enhex

Reputation: 157

A safe version of orlp's char* answer using unique_ptr:

std::string str = "string";
auto cstr = std::make_unique<char[]>(str.length() + 1);
strcpy(cstr.get(), str.c_str());

Upvotes: 4

TS.PARK
TS.PARK

Reputation: 41

You can make it using iterator.

std::string str = "string";
std::string::iterator p=str.begin();
char* chr = &(*p);

Good luck.

Upvotes: 4

zangw
zangw

Reputation: 48526

Here is one more robust version from Protocol Buffer

char* string_as_array(string* str)
{
    return str->empty() ? NULL : &*str->begin();
}

// test codes
std::string mystr("you are here");
char* pstr = string_as_array(&mystr);
cout << pstr << endl; // you are here

Upvotes: 5

user5616653
user5616653

Reputation:

Alternatively , you can use vectors to get a writable char* as demonstrated below;

//this handles memory manipulations and is more convenient
string str;
vector <char> writable (str.begin (), str.end) ;
writable .push_back ('\0'); 
char* cstring = &writable[0] //or &*writable.begin () 

//Goodluck  

Upvotes: 3

cegprakash
cegprakash

Reputation: 3125

char* result = strcpy((char*)malloc(str.length()+1), str.c_str());

Upvotes: 3

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385325

  • If you just want a C-style string representing the same content:

    char const* ca = str.c_str();
    
  • If you want a C-style string with new contents, one way (given that you don't know the string size at compile-time) is dynamic allocation:

    char* ca = new char[str.size()+1];
    std::copy(str.begin(), str.end(), ca);
    ca[str.size()] = '\0';
    

    Don't forget to delete[] it later.

  • If you want a statically-allocated, limited-length array instead:

    size_t const MAX = 80; // maximum number of chars
    char ca[MAX] = {};
    std::copy(str.begin(), (str.size() >= MAX ? str.begin() + MAX : str.end()), ca);
    

std::string doesn't implicitly convert to these types for the simple reason that needing to do this is usually a design smell. Make sure that you really need it.

If you definitely need a char*, the best way is probably:

vector<char> v(str.begin(), str.end());
char* ca = &v[0]; // pointer to start of vector

Upvotes: 19

Genocide_Hoax
Genocide_Hoax

Reputation: 853

This will also work

std::string s;
std::cout<<"Enter the String";
std::getline(std::cin, s);
char *a=new char[s.size()+1];
a[s.size()]=0;
memcpy(a,s.c_str(),s.size());
std::cout<<a;  

Upvotes: 2

Jeffery Thomas
Jeffery Thomas

Reputation: 42598

For completeness' sake, don't forget std::string::copy().

std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];

str.copy(chrs, MAX);

std::string::copy() doesn't NUL terminate. If you need to ensure a NUL terminator for use in C string functions:

std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];

memset(chrs, '\0', MAX);
str.copy(chrs, MAX-1);

Upvotes: 4

Nordic Mainframe
Nordic Mainframe

Reputation: 28767

If I'd need a mutable raw copy of a c++'s string contents, then I'd do this:

std::string str = "string";
char* chr = strdup(str.c_str());

and later:

free(chr); 

So why don't I fiddle with std::vector or new[] like anyone else? Because when I need a mutable C-style raw char* string, then because I want to call C code which changes the string and C code deallocates stuff with free() and allocates with malloc() (strdup uses malloc). So if I pass my raw string to some function X written in C it might have a constraint on it's argument that it has to allocated on the heap (for example if the function might want to call realloc on the parameter). But it is highly unlikely that it would expect an argument allocated with (some user-redefined) new[]!

Upvotes: 51

Rob K
Rob K

Reputation: 8926

To be strictly pedantic, you cannot "convert a std::string into a char* or char[] data type."

As the other answers have shown, you can copy the content of the std::string to a char array, or make a const char* to the content of the std::string so that you can access it in a "C style".

If you're trying to change the content of the std::string, the std::string type has all of the methods to do anything you could possibly need to do to it.

If you're trying to pass it to some function which takes a char*, there's std::string::c_str().

Upvotes: 5

Mark B
Mark B

Reputation: 96301

Assuming you just need a C-style string to pass as input:

std::string str = "string";
const char* chr = str.c_str();

Upvotes: 8

Related Questions