118

I would like to convert string to char array but not char*. I know how to convert string to char* (by using malloc or the way I posted it in my code) - but that's not what I want. I simply want to convert string to char[size] array. Is it possible?

#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;

int main()
{
    // char to string
    char tab[4];
    tab[0] = 'c';
    tab[1] = 'a';
    tab[2] = 't';
    tab[3] = '\0';
    string tmp(tab);
    cout << tmp << "\n";

    // string to char* - but thats not what I want

    char *c = const_cast<char*>(tmp.c_str());
    cout << c << "\n";

    //string to char
    char tab2[1024];
    // ?

    return 0;
}
Ziezi
  • 6,049
  • 3
  • 34
  • 45
Brian Brown
  • 2,985
  • 14
  • 43
  • 73

11 Answers11

145

Simplest way I can think of doing it is:

string temp = "cat";
char tab2[1024];
strcpy(tab2, temp.c_str());

For safety, you might prefer:

string temp = "cat";
char tab2[1024];
strncpy(tab2, temp.c_str(), sizeof(tab2));
tab2[sizeof(tab2) - 1] = 0;

or could be in this fashion:

string temp = "cat";
char * tab2 = new char [temp.length()+1];
strcpy (tab2, temp.c_str());
G. Sliepen
  • 5,327
  • 1
  • 11
  • 25
Chowlett
  • 42,941
  • 17
  • 109
  • 142
  • 11
    The catch with `strncpy` is that it won't null-terminate if it reaches the size before it finds a null in the source string. Gotta be careful with that too! – Fred Larson Nov 08 '12 at 17:15
  • @FredLarson - Good point! Worth putting `tab2[sizeof(tab2) - 1] = 0;` after it, then? – Chowlett Nov 08 '12 at 17:16
  • 1
    Yes, I think that's a reasonable way to handle it. – Fred Larson Nov 08 '12 at 17:17
  • @Chowlett: you mean: should I add this line just after `strncpy`? – Brian Brown Nov 08 '12 at 17:18
  • `strncpy` is **not** for safety. If you want a range-checked copy, use `strcpy_s`. – Pete Becker Nov 08 '12 at 17:23
  • @BrianBrown - `strcpy_s` is in C99. – Pete Becker Nov 08 '12 at 17:30
  • 1
    strncpy is for safety in that strncpy will not overrun the buffer you give it. Also strcpy_s is not in C99, but it has recently been added in C11. – bames53 Nov 08 '12 at 17:36
  • 8
    I love the way people abuse the word *safety*... oh, there's not enough room for the string, so let's truncate it.. oh, we accidentally removed the info about the patient's life threatening drug allergy.. but we don't have a buffer overrun anymore. well, I *guess* it's *safe*... – Karoly Horvath May 15 '15 at 14:06
  • 5
    @KarolyHorvath - safety in different domains. Obviously, you need to check your functional requirements and Not Do Stupid Things. But if you overrun the buffer you lose any guarantee of knowing what will happen. Correct coding ensures the program is "safe" to run on your OS. Correct _thinking_ ensures the program is "safe" at doing what the user needs. – Chowlett Jun 17 '15 at 11:11
  • 1
    @Chowlett: Obviously. It's the second aspect people seem to be ignoring when they abuse the word. – Karoly Horvath Jun 17 '15 at 17:20
  • On POSIX-like systems you could also use `strdup` for this. – fuz Jul 31 '15 at 13:42
  • You can use C++17's `std::size` instead of `sizeof`, which is more appropriate in this case and also more similar for wchar_t, Unicode characters, etc. Also note that [`strncpy`](https://blogs.msdn.microsoft.com/oldnewthing/20050107-00/?p=36773/) does not require null character termination. – Matthias Jan 16 '18 at 18:31
64

Ok, i am shocked that no one really gave a good answer, now my turn. There are two cases;

  1. A constant char array is good enough for you so you go with,

    const char *array = tmp.c_str();
    
  2. Or you need to modify the char array so constant is not ok, then just go with this

    char *array = &tmp[0];
    

Both of them are just assignment operations and most of the time that is just what you need, if you really need a new copy then follow other fellows answers.

Dr. Zow
  • 3
  • 2
rad
  • 916
  • 6
  • 15
  • 7
    He wants a char array, not a char * – harogaston Oct 08 '15 at 00:02
  • 11
    The pointer he created is the same thing as a char array. An array variable in C and C++ is just a pointer to the first element in the array. – JustinCB Jun 01 '17 at 17:39
  • 4
    @JustinC.B. not really! array variables **might decay** into pointers but they are not same in C++. e.g. `std::size(elem)` in C++ is well defined when `elem` is a `char array` but it fails to compile when `elem` is a `char*` or `const char*`, you can see it at [here](https://coliru.stacked-crooked.com/a/199ae9f32a48dcc7) – aniliitb10 Jan 15 '19 at 19:27
17

Easiest way to do it would be this

std::string myWord = "myWord";
char myArray[myWord.size()+1];//as 1 char space for null is also required
strcpy(myArray, myWord.c_str());
Community
  • 1
  • 1
14
str.copy(cstr, str.length()+1); // since C++11
cstr[str.copy(cstr, str.length())] = '\0';  // before C++11
cstr[str.copy(cstr, sizeof(cstr)-1)] = '\0';  // before C++11 (safe)

It's a better practice to avoid C in C++, so std::string::copy should be the choice instead of strcpy.

Youka
  • 2,460
  • 18
  • 31
6

Just copy the string into the array with strcpy.

David Schwartz
  • 166,415
  • 16
  • 184
  • 259
5

Try this way it should be work.

string line="hello world";
char * data = new char[line.size() + 1];
copy(line.begin(), line.end(), data);
data[line.size()] = '\0'; 
3

Try strcpy(), but as Fred said, this is C++, not C

Marrow Gnawer
  • 477
  • 6
  • 20
2

You could use strcpy(), like so:

strcpy(tab2, tmp.c_str());

Watch out for buffer overflow.

Fred Larson
  • 56,061
  • 15
  • 106
  • 157
2

If you don't know the size of the string beforehand, you can dynamically allocate an array:

auto tab2 = std::make_unique<char[]>(temp.size() + 1);
std::strcpy(tab2.get(), temp.c_str());
emlai
  • 37,861
  • 9
  • 87
  • 140
0

If you're using C++11 or above, I'd suggest using std::snprintf over std::strcpy or std::strncpy because of its safety (i.e., you determine how many characters can be written to your buffer) and because it null-terminates the string for you (so you don't have to worry about it). It would be like this:

#include <string>
#include <cstdio>

std::string tmp = "cat";
char tab2[1024];
std::snprintf(tab2, sizeof(tab2), "%s", tmp.c_str());

In C++17, you have this alternative:

#include <string>
#include <cstdio>
#include <iterator>

std::string tmp = "cat";
char tab2[1024];
std::snprintf(tab2, std::size(tab2), "%s", tmp.c_str());
luizfls
  • 376
  • 4
  • 11
-1

Well I know this maybe rather dumb than and simple, but I think it should work:

string n;
cin>> n;
char b[200];
for (int i = 0; i < sizeof(n); i++)
{
    b[i] = n[i];
    cout<< b[i]<< " ";
}
tmthydvnprt
  • 8,832
  • 7
  • 49
  • 66
SquircKle
  • 1
  • 1
  • Well, not really. You're just assuming that ``n`` can't be larger than ``b``. It would crash if ``n>b``. Better to use the ``strcpy`` function already provided. Edit: At some cases it might be even better to use ``strcpy_s`` as it adds check for NULL pointers (if your platform supports it) – droidballoon Sep 30 '17 at 19:24