Home:ALL Converter>How to convert a std::string to const char* or char*

How to convert a std::string to const char* or char*

Ask Time:2008-12-08T03:30:56         Author:user37875

Json Formatter

How can I convert an std::string to a char* or a const char*?

Author:user37875,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/347949/how-to-convert-a-stdstring-to-const-char-or-char
Gabriel Staples :

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++.\nHow to use a modern C++ std::string as a C-style read/writable char* or read-only null-terminated const char*\n\nHow can I convert a std::string to a char* or a const char*?\n\nDespite 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.\nAll of the usages below require C++11 or later, except for the char* data() call, which requires C++17 or later.\nTo 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.\nQuick summary:\n#include <string>\nconstexpr size_t BUFFER_SIZE = 100;\nstd::string str;\n// IMPORTANT: pre-allocate the underlying buffer to guarantee what size it is\nstr.resize(BUFFER_SIZE); \n\n// -----------------------------------------------------------------------------\n// Get read-writeable access to the underlying `char*` C-string at index i\n// -----------------------------------------------------------------------------\n\nchar* c_str1 = &str[i]; // <=== my favorite!\nchar* c_str2 = str.data() + i;\nchar* c_str3 = &(*str.begin()) + i;\n\n// NB: the C-strings above are NOT guaranteed to be null-terminated, so manually\n// write in a null terminator at the index location where you want it if\n// desired. Ex:\n//\n// 1. write a null terminator at some arbitrary position you choose (index 10\n// here)\nc_str1[10] = '\\0'; \n// 2. write a null terminator at the last guaranteed valid position in the \n// underlying C-string/array of chars\nc_str2[str.size() - i - 1] = '\\0';\n\n// -----------------------------------------------------------------------------\n// Get read-only access to the underlying `const char*` C-string at index i\n// -----------------------------------------------------------------------------\nconst char* const_c_str1 = &str[i];\nconst char* const_c_str2 = str.c_str() + i; // guaranteed to be null-terminated,\n // but not necessarily at the\n // position you desire; the\n // guaranteed null terminator will\n // be at index location \n // `str.size()`\n\nSummary:\nIf in a hurry and you need:\n\nA read-writable char* C-string of the underlying buffer: just use section A Technique 1 in the code example just below: char* c_str1 = &str[i];.\n\nJust be sure to pre-allocate the underlying buffer size first via str.resize(BUFFER_SIZE), if needed, is all, to ensure the underlying buffer is big enough for your needs.\n\n\nA read-only const char* C-string of the underlying buffer: use the same thing as above (const char* const_c_str1 = &str[i];), or const char* const_c_str1 = str.c_str() + i;.\n\n#include <string>\n\nconstexpr size_t BUFFER_SIZE = 100;\n\nstd::string str;\n// IMPORTANT: pre-allocate the underlying buffer to guarantee what size it is\nstr.resize(BUFFER_SIZE); \n\n// =============================================================================\n// Now you can use the `std::string`'s underlying buffer directly as a C-string\n// =============================================================================\n\n// ---------------------------------------------------------\n// A. As a read-writeable `char*` C-string\n// ---------------------------------------------------------\n\n// Technique 1 [best option if using C++11]: array indexing using `operator[]` \n// to obtain a char, followed by obtaining its address with `&`\n// - Documentation: \n// https://en.cppreference.com/w/cpp/string/basic_string/operator_at\nchar* c_str1 = &str[0];\nchar* c_str2 = &str[10];\nchar* c_str3 = &str[33];\n// etc. \n\n// Technique 2 [best option if using C++17]: use the `.data()` method to obtain\n// a `char*` directly.\n// - Documentation: \n// https://en.cppreference.com/w/cpp/string/basic_string/data\nchar* c_str11 = str.data(); // same as c_str1 above\nchar* c_str12 = str.data() + 10; // same as c_str2 above\nchar* c_str13 = str.data() + 33; // same as c_str3 above\n\n// Technique 3 [fine in C++11 or later, but is awkward, so don't do this. It is\n// for demonstration and learning purposes only]: use the `.begin()` method to\n// obtain an iterator to the first char, and then use the iterator's \n// `operator*()` dereference method to obtain the iterator's `char`\n// `value_type`, and then take the address of that to obtain a `char*`\n// - Documentation:\n// - https://en.cppreference.com/w/cpp/string/basic_string/begin\n// - https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator\nchar* c_str21 = &(*str.begin()); // same as c_str1 and c_str11 above\nchar* c_str22 = &(*str.begin()) + 10; // same as c_str2 and c_str12 above\nchar* c_str23 = &(*str.begin()) + 33; // same as c_str3 and c_str13 above\n\n\n// ---------------------------------------------------------\n// B. As a read-only, null-terminated `const char*` C-string\n// ---------------------------------------------------------\n\n// - Documentation:\n// https://en.cppreference.com/w/cpp/string/basic_string/c_str\n\nconst char* const_c_str1 = str.c_str(); // a const version of c_str1 above\nconst char* const_c_str2 = str.c_str() + 10; // a const version of c_str2 above\nconst char* const_c_str3 = str.c_str() + 33; // a const version of c_str3 above\n\nNote that you can also use the .at(i) and .front() std::string methods too, but I won't go into those since I think my examples are sufficient. For their documentation, see:\n\nhttps://en.cppreference.com/w/cpp/string/basic_string/at\nhttps://en.cppreference.com/w/cpp/string/basic_string/front\n\nDetails:\nSee also the note just above. I'm not going to cover the techniques using the .at(i) and .front() std::string methods, since I think the several techniques I already present are sufficient.\n1. Use a std::string as a read/writable char*\nTo 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:\n\nIf pos > size(), the behavior is undefined.\n\nThe resize() method is what changes the size, not the reserve() method, which changes only the capacity().\nEx:\n#include <cstring> // `strcpy()`\n#include <iostream>\n#include <string>\n\n\nconstexpr size_t BUFFER_SIZE = 100;\n\nstd::string str;\nstr.resize(BUFFER_SIZE); // pre-allocate the underlying buffer\n// check the size\nstd::cout << "str.size() = " << str.size() << "\\n";\n\nFor all examples below, assume you have these C-strings:\nconstexpr char cstr1[] = "abcde ";\nconstexpr char cstr2[] = "fghijk";\n\nOnce you have pre-allocated an underlying buffer which is sufficiently large with resize(), you can then access the underlying buffer as\na char* in at least 3 ways:\n\nTechnique 1 [best option if using C++11]: array indexing using operator[] to obtain a char, followed by obtaining its address with &. Ex:\nchar* c_str;\nc_str = &str[0];\nc_str = &str[5]; \n// etc.\n\n// Write these 2 C-strings into a `std::string`'s underlying buffer\nstrcpy(&str[0], cstr1);\nstrcpy(&str[sizeof(cstr1) - 1], cstr2); // `- 1` to overwrite the first \n // null terminator\n\n// print the string\nstd::cout << str << "\\n"; // output: `abcde fghijk`\n\nWhat 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:\nstd::string str2;\nstd::string* pstr = &str2;\npstr->resize(BUFFER_SIZE);\nc_str = &(*pstr)[0]; // <=== dereference the ptr 1st before indexing into it\n// Or, to make the order of precedence \n// (https://en.cppreference.com/w/cpp/language/operator_precedence) really\n// obvious, you can optionally add extra parenthesis like this:\nc_str = &((*pstr)[0]);\n\n\nTechnique 2 [best option if using C++17]: use the .data() method to obtain a char* directly. Ex:\nchar* c_str;\nc_str = str.data();\nc_str = str.data() + 5;\n// etc.\n\n// Write these 2 C-strings into the `std::string`'s underlying buffer\nstrcpy(str.data(), cstr1);\nstrcpy(str.data() + (sizeof(cstr1) - 1), cstr2); // `- 1` to overwrite the\n // first null terminator\n\n// print the string\nstd::cout << str << "\\n"; // output: `abcde fghijk`\n\n\nTechnique 3 [fine in C++11 and later, but is awkward, so don't do this. It is for demonstration and learning purposes only]: use the .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:\nchar* c_str;\nc_str = &(*str.begin());\nc_str = &(*str.begin()) + 5;\n// etc.\n\n// Write these 2 C-strings into the `std::string`'s underlying buffer\nstrcpy(&(*str.begin()), cstr1);\nstrcpy(&(*str.begin()) + (sizeof(cstr1) - 1), cstr2); // `- 1` to overwrite \n // the first null \n // terminator\n\n// print the string\nstd::cout << str << "\\n"; // output: `abcde fghijk`\n\n\n\nSomething 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:\nstd::cout << strlen(str.c_str()) << "\\n"; // prints `12` in the examples above\n\n// instead of:\nstd::cout << str.size() << "\\n"; // prints `100` in the examples above\n\n2. Access a std::string as a read-only, null-terminated const char*\nTo 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!\nExample:\nstd::string str = "hello world";\nprintf("%s\\n", str.c_str());\n\nReferences\n\n(questions on Stack Overflow)\n\nHow to convert a std::string to const char* or char*:\nHow to convert a std::string to const char* or char*\nDirectly write into char* buffer of std::string:\nDirectly write into char* buffer of std::string\nIs there a way to get std:string's buffer:\nIs there a way to get std:string's buffer\n\n\n(my content)\n\n[my test code] string__use_std_string_as_a_c_str_buffer.cpp\n[my Q] See the "Adjacently related" section at the bottom of my question here:\nWhat is a call to `char()`, `uint8_t()`, `int64_t()`, integer `T()`, etc, as a function in C++?\n*****+ [my comments about pre-allocating a buffer in the std::string]:\nDirectly write into char* buffer of std::string\n*****+ [my comment on how to pre-allocate storage in a std::string, to be used as a char* buffer]\nIs there a way to get std:string's buffer\n\n\n(from the cppreference.com community wiki)\n\nhttps://en.cppreference.com/w/cpp/string/basic_string:\n\nThe elements of a basic_string are stored contiguously, that is, for a basic_string s, &*(s.begin\n() + n) == &*s.begin() + n for any n in [0, s.size()), or, equivalently, a pointer to s[0] can\nbe passed to functions that expect a pointer to the first element of a null-terminated\n(since C++11)CharT[] array.\n\n\nhttps://en.cppreference.com/w/cpp/string/basic_string/operator_at\n\nReturns a reference to the character at specified location pos. No bounds checking is performed.\nIf pos > size(), the behavior is undefined.\n\n\nhttps://en.cppreference.com/w/cpp/string/basic_string/resize\n\nhttps://en.cppreference.com/w/cpp/string/basic_string/reserve\n\nhttps://en.cppreference.com/w/cpp/string/basic_string/data\n\nhttps://en.cppreference.com/w/cpp/string/basic_string/c_str\n\nhttps://en.cppreference.com/w/cpp/string/basic_string/clear\n\n\n\n",
2022-06-03T06:15:39
Mark Ransom :

Use the .c_str() method for const char *.\n\nYou 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).\n\nThere 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?.\n\nNote 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.",
2008-12-07T19:31:50
Pixelchemist :

C++17\n\nC++17 (upcoming standard) changes the synopsis of the template basic_string adding a non const overload of data():\n\n\n charT* data() noexcept;\n \n Returns: A pointer p such that p + i == &operator for each i in [0,size()].\n\n\n\n\nCharT const * from std::basic_string<CharT>\n\nstd::string const cstr = { \"...\" };\nchar const * p = cstr.data(); // or .c_str()\n\n\nCharT * from std::basic_string<CharT>\n\nstd::string str = { \"...\" };\nchar * p = str.data();\n\n\nC++11\n\nCharT const * from std::basic_string<CharT>\n\nstd::string str = { \"...\" };\nstr.c_str();\n\n\nCharT * from std::basic_string<CharT>\n\nFrom C++11 onwards, the standard says:\n\n\n \n The char-like objects in a basic_string object shall be stored contiguously. That is, for any basic_string object s, the identity &*(s.begin() + n) == &*s.begin() + n shall hold for all values of n such that 0 <= n < s.size().\n \n \n \n \n \n const_reference operator[](size_type pos) const; reference operator[](size_type pos); \n \n Returns: *(begin() + pos) if pos < size(), otherwise a reference to an object of type CharT with value CharT(); the referenced value shall not be modified.\n \n \n \n \n \n const charT* c_str() const noexcept;const charT* data() const noexcept;\n \n Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()].\n \n\n\nThere are severable possible ways to get a non const character pointer.\n\n1. Use the contiguous storage of C++11\n\nstd::string foo{\"text\"};\nauto p = &*foo.begin();\n\n\nPro\n\n\nSimple and short\nFast (only method with no copy involved)\n\n\nCons\n\n\nFinal '\\0' is not to be altered / not necessarily part of the non-const memory.\n\n\n2. Use std::vector<CharT>\n\nstd::string foo{\"text\"};\nstd::vector<char> fcv(foo.data(), foo.data()+foo.size()+1u);\nauto p = fcv.data();\n\n\nPro\n\n\nSimple\nAutomatic memory handling\nDynamic\n\n\nCons\n\n\nRequires string copy\n\n\n3. Use std::array<CharT, N> if N is compile time constant (and small enough)\n\nstd::string foo{\"text\"};\nstd::array<char, 5u> fca;\nstd::copy(foo.data(), foo.data()+foo.size()+1u, fca.begin());\n\n\nPro\n\n\nSimple\nStack memory handling\n\n\nCons\n\n\nStatic\nRequires string copy\n\n\n4. Raw memory allocation with automatic storage deletion\n\nstd::string foo{ \"text\" };\nauto p = std::make_unique<char[]>(foo.size()+1u);\nstd::copy(foo.data(), foo.data() + foo.size() + 1u, &p[0]);\n\n\nPro\n\n\nSmall memory footprint\nAutomatic deletion\nSimple\n\n\nCons\n\n\nRequires string copy\nStatic (dynamic usage requires lots more code)\nLess features than vector or array\n\n\n5. Raw memory allocation with manual handling\n\nstd::string foo{ \"text\" };\nchar * p = nullptr;\ntry\n{\n p = new char[foo.size() + 1u];\n std::copy(foo.data(), foo.data() + foo.size() + 1u, p);\n // handle stuff with p\n delete[] p;\n}\ncatch (...)\n{\n if (p) { delete[] p; }\n throw;\n}\n\n\nPro\n\n\nMaximum 'control'\n\n\nCon\n\n\nRequires string copy\nMaximum liability / susceptibility for errors\nComplex\n",
2016-01-12T15:53:11
devsaw :

Just see this:\n\nstring str1(\"stackoverflow\");\nconst char * str2 = str1.c_str();\n\n\nHowever, note that this will return a const char *.\n\nFor a char *, use strcpy to copy it into another char array.",
2013-05-12T08:18:16
Alessandro Teruzzi :

I am working with an API with a lot of functions that get a char* as an input.\nI have created a small class to face this kind of problem, and I have implemented the RAII idiom.\nclass DeepString\n{\n DeepString(const DeepString& other);\n DeepString& operator=(const DeepString& other);\n char* internal_; \n \n public:\n explicit DeepString( const string& toCopy): \n internal_(new char[toCopy.size()+1]) \n {\n strcpy(internal_,toCopy.c_str());\n }\n ~DeepString() { delete[] internal_; }\n char* str() const { return internal_; }\n const char* c_str() const { return internal_; }\n};\n\nAnd you can use it as:\nvoid aFunctionAPI(char* input);\n\n// other stuff\n\naFunctionAPI("Foo"); //this call is not safe. if the function modified the \n //literal string the program will crash\nstd::string myFoo("Foo");\naFunctionAPI(myFoo.c_str()); //this is not compiling\naFunctionAPI(const_cast<char*>(myFoo.c_str())); //this is not safe std::string \n //implement reference counting and \n //it may change the value of other\n //strings as well.\nDeepString myDeepFoo(myFoo);\naFunctionAPI(myFoo.str()); //this is fine\n\nI have called the class DeepString because it is creating a deep and unique copy (the DeepString is not copyable) of an existing string.",
2011-03-29T13:32:16
cegprakash :

char* result = strcpy((char*)malloc(str.length()+1), str.c_str());\n",
2014-07-12T12:06:36
SHAH MD IMRAN HOSSAIN :

Converting from c++ std string to C style string is really easy now.\nFor that we have string::copy function which will easily convert std string to C style string. reference\nstring::copy functions parameters serially\n\nchar string pointer\nstring size, how many characters will b copied\nposition, from where character copy will start\n\nAnother important thing,\nThis function does not append a null character at the end of operation. So, we need to put it manually.\nCode exam are in below -\n// char string\nchar chText[20];\n\n// c++ string\nstring text = "I am a Programmer";\n\n// conversion from c++ string to char string\n// this function does not append a null character at the end of operation\ntext.copy(chText, text.size(), 0);\n\n// we need to put it manually\nchText[text.size()] = '\\0';\n\n// below statement prints "I am a Programmer"\ncout << chText << endl;\n\nVice Versa, Converting from C style string to C++ std string is lot more easier\nThere is three ways we can convert from C style string to C++ std string\nFirst one is using constructor,\nchar chText[20] = "I am a Programmer";\n// using constructor\nstring text(chText);\n\nSecond one is using string::assign method\n// char string\nchar chText[20] = "I am a Programmer";\n\n// c++ string\nstring text;\n\n// convertion from char string to c++ string\n// using assign function\ntext.assign(chText);\n\nThird one is assignment operator(=), in which string class uses operator overloading\n// char string\nchar chText[20] = "I am a Programmer";\n\n// c++ string\n// convertion from char string to c++ string using assignment operator overloading\nstring text = chText;\n\nthird one can be also write like below -\n// char string\nchar chText[20] = "I am a Programmer";\n\n// c++ string\nstring text;\n\n\n// convertion from char string to c++ string\ntext = chText;\n",
2021-10-27T20:27:22
Vineeth Peddi :

let's say,\nstring str="stack";\n1)converting string to char*\n char* s_rw=&str[0]; \n\nThe above char*(i.e., s_rw) is readable and writeable and points to the base\naddress of the string which needs to be converted to char*\n2)Converting string to const char*\n const char* s_r=&str[0];\n\nThe above const char* (i.e., s_r) is readable but not writeable and points to the\nbase address of the string.",
2021-06-17T06:50:08
yy