Как преобразовать строку в массив символов в C ++?

104

Я хотел бы преобразовать stringв charмассив, но нет char*. Я знаю, как преобразовать строку в char*(используя mallocили как я разместил ее в своем коде), но это не то, что я хочу. Я просто хочу преобразовать stringв char[size]массив. Является ли это возможным?

#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;
}
Брайан Браун
источник
12
Похоже, это C ++, а не C.
Фред Ларсон
@FredLarson: хорошо, отредактировано, спасибо
Брайан Браун
3
возможный дубликат std :: string в char *
cegprakash

Ответы:

125

Самый простой способ сделать это:

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

В целях безопасности вы можете предпочесть:

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

или может быть так:

string temp = "cat";
char * tab2 = new char [temp.length()+1];
strcpy (tab2, temp.c_str());
Chowlett
источник
9
Загвоздка strncpyзаключается в том, что он не будет завершаться нулевым символом, если достигнет размера до того, как найдет нуль в исходной строке. С этим тоже нужно быть осторожным!
Фред Ларсон
1
Да, я думаю, что это разумный способ справиться с этим.
Фред Ларсон
1
strncpy предназначен для обеспечения безопасности, поскольку strncpy не будет переполнять буфер, который вы ему предоставили. Также strcpy_s отсутствует в C99, но недавно был добавлен в C11.
bames53
6
Мне нравится, как люди злоупотребляют словом « безопасность» ... о, здесь недостаточно места для строки, так что давайте ее усечем ... о, мы случайно удалили информацию об опасной для жизни аллергии на лекарства ... но у нас нет переполнение буфера больше. ну, я думаю, это безопасно ...
Кароли Хорват
4
@KarolyHorvath - безопасность в разных сферах. Очевидно, вам нужно проверить свои функциональные требования и не делать глупостей. Но если вы переполните буфер, вы потеряете любую гарантию того, что знаете, что произойдет. Правильное кодирование гарантирует, что программа «безопасна» для работы в вашей ОС. Правильное мышление гарантирует, что программа «безопасно» делает то, что нужно пользователю.
Chowlett
58

Хорошо, я шокирован тем, что на самом деле никто не дал хорошего ответа, теперь моя очередь. Есть два случая;

  1. Для вас достаточно постоянного массива символов, поэтому вы можете использовать

    const char *array = tmp.c_str();
  2. Или вам нужно изменить массив символов, чтобы константа не подходила, тогда просто используйте это

    char *array = &tmp[0];

Оба они - просто операции присваивания, и в большинстве случаев это именно то, что вам нужно, если вам действительно нужна новая копия, следуйте ответам других товарищей.

рад
источник
7
Он хочет массив символов, а не символ *
harogaston 08
10
Созданный им указатель - это то же самое, что и массив символов. Переменная массива в C и C ++ - это просто указатель на первый элемент в массиве.
JustinCB 01
@ JustinC.B. на самом деле, нет! переменные массива могут распадаться на указатели, но в C ++ они не совпадают. например, std::size(elem)в C ++ хорошо определен, когда elemявляется a, char arrayно он не компилируется, когдаelem является char*или const char*, вы можете увидеть это здесь
aniliitb10
17

Самый простой способ сделать это - это

std::string myWord = "myWord";
char myArray[myWord.size()+1];//as 1 char space for null is also required
strcpy(myArray, myWord.c_str());
Сообщество
источник
15
Размер массива должен быть константой времени компиляции в C ++.
Interjay
12
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)

Лучше избегать использования C в C ++, поэтому вместо strcpy следует использовать std :: string :: copy .

Юка
источник
6

Просто скопируйте строку в массив с помощью strcpy.

Дэвид Шварц
источник
5

Попробуйте, так должно получиться.

string line="hello world";
char * data = new char[line.size() + 1];
copy(line.begin(), line.end(), data);
data[line.size()] = '\0'; 
Таринду Дханушка
источник
4

Попробуйте strcpy (), но, как сказал Фред, это C ++, а не C

Грызущий костный мозг
источник
2

Вы можете использовать strcpy()вот так:

strcpy(tab2, tmp.c_str());

Остерегайтесь переполнения буфера.

Фред Ларсон
источник
2

Если вы заранее не знаете размер строки, вы можете динамически выделить массив:

auto tab2 = std::make_unique<char[]>(temp.size() + 1);
std::strcpy(tab2.get(), temp.c_str());
Emlai
источник
0

Хорошо, я знаю, что это может быть скорее глупо, чем просто, но я думаю, что это должно сработать:

string n;
cin>> n;
char b[200];
for (int i = 0; i < sizeof(n); i++)
{
    b[i] = n[i];
    cout<< b[i]<< " ";
}
SquircKle
источник
Ну не совсем. Вы просто предполагаете, что nэто не может быть больше b. Если бы он рухнул n>b. Лучше использовать strcpyуже предоставленную функцию. Изменить: в некоторых случаях может быть даже лучше использовать, strcpy_sпоскольку он добавляет проверку на указатели NULL (если ваша платформа поддерживает это)
droidballoon
0

Если вы используете C ++ 11 или выше, я бы предложил использовать std::snprintfover std::strcpyили std::strncpyиз-за его безопасности (то есть вы определяете, сколько символов может быть записано в ваш буфер) и потому что он завершает строку за вас нулевым символом (так что вам не о чем беспокоиться). Это было бы так:

#include <string>
#include <cstdio>

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

В C ++ 17 у вас есть альтернатива:

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

std::string tmp = "cat";
char tab2[1024];
std::snprintf(tab2, std::size(tab2), "%s", tmp.c_str());
Luizfls
источник