Як перетворити рядок у масив char у C ++?


103

Я хотів би перетворити 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 to char *
cegprakash

Відповіді:


123

Найпростіший спосіб, що я можу зробити це:

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());

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 так, щоб константа не була нормальною, тоді просто переходьте до цього

    char *array = &tmp[0];

Вони обидва - це лише операції з присвоєння, і більшість часу це саме те, що вам потрібно, якщо вам справді потрібна нова копія, то дотримуйтесь відповідей інших колег.


7
Він хоче масив char, а не char *
harogaston

10
Створений ним вказівник - це те саме, що і масив char. Змінна масиву в C і C ++ - це лише вказівник на перший елемент масиву.
JustinCB

@ JustinC.B. не зовсім! Змінні масиву можуть розпадатися на покажчики, але вони не однакові в C ++. наприклад, std::size(elem)в C ++ добре визначено, коли elemє, char arrayале це не вдається зібрати, коли elemце, char*або const char*ви можете побачити це тут
aniliitb10

16

Найпростішим способом було б це

std::string myWord = "myWord";
char myArray[myWord.size()+1];//as 1 char space for null is also required
strcpy(myArray, myWord.c_str());

14
Розмір масиву повинен бути константою часу компіляції в 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 ++, тому std :: string :: copy має бути вибором замість strcpy .



5

Спробуйте так, як це має бути робота.

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


2

Ви можете використовувати strcpy()так:

strcpy(tab2, tmp.c_str());

Слідкуйте за переливом буфера.


2

Якщо заздалегідь не знаєте розмір рядка, ви можете динамічно виділити масив:

auto tab2 = std::make_unique<char[]>(temp.size() + 1);
std::strcpy(tab2.get(), temp.c_str());

0

Ну, я знаю, це може бути досить німим, ніж простим, але я думаю, що це має працювати:

string n;
cin>> n;
char b[200];
for (int i = 0; i < sizeof(n); i++)
{
    b[i] = n[i];
    cout<< b[i]<< " ";
}

Ну не дуже. Ви просто припускаєте, що nне може бути більше, ніж b. Він би зазнав краху, якби n>b. Краще скористатися strcpyфункцією, яка вже надана. Редагувати: У деяких випадках це може бути навіть краще використовувати, strcpy_sоскільки він додає чек на покажчики NULL (якщо ваша платформа підтримує це)
droidballoon

0

Якщо ви використовуєте C ++ 11 або вище, я б запропонував використовувати std::snprintfнад 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());
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.