Std::string до char *

Я хочу преобразовать std::string в тип данных char * или char [].

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

Результаты в: "ошибка: невозможно преобразовать 'std::string в' char..." .

Какие существуют методы для этого?

Ответ 1

Он не будет автоматически конвертировать (слава богу). Вам нужно будет использовать метод c_str(), чтобы получить версию строки C.

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

Обратите внимание, что он возвращает const char *; вам не разрешено изменять строку стиля C, возвращаемую c_str(). Если вы хотите обработать его, сначала скопируйте его:

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

Или в современном С++:

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

Ответ 3

Если мне понадобится изменяемая необработанная копия содержимого строки С++, я бы сделал следующее:

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

и позже:

free(chr); 

Так почему бы мне не поиграть с std::vector или новым [], как кто-либо еще? Потому что, когда мне нужна изменчивая строковая строка char * в C-стиле, тогда, поскольку я хочу вызвать код C, который изменяет строку, а C-код освобождает материал с помощью free() и выделяет с помощью malloc() (strdup использует malloc). Поэтому, если я передаю свою исходную строку некоторой функции X, написанной на C, она может иметь ограничение на ее аргумент, который он должен выделить в куче (например, если функция может захотеть вызвать realloc для параметра). Но маловероятно, что он ожидал бы, что аргумент будет выделен (некоторым пользовательским переопределенным) новым []!

Ответ 4

(Этот ответ относится только к С++ 98.)

Пожалуйста, не используйте 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*

Ответ 5

  • Если вы просто хотите, чтобы строка C-стиля представляла один и тот же контент:

    char const* ca = str.c_str();
    
  • Если вам нужна строка стиля C с новым содержимым, один из способов (если вы не знаете размер строки во время компиляции) - это динамическое распределение:

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

    Не забывайте delete[] позже.

  • Если вам нужен статически распределенный массив с ограниченной длиной:

    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 неявно конвертируется в эти типы по той простой причине, что это необходимо, как правило, запах дизайна. Убедитесь, что вам это действительно нужно.

Если вам определенно нужен char*, лучший способ:

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

Ответ 6

Предполагая, что вам просто нужна строка стиля C для ввода в качестве входных данных:

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

Ответ 7

Чтобы быть строго педантичным, вы не можете "преобразовать std::string в тип данных char * или char []".

Как показали другие ответы, вы можете скопировать содержимое массива std::string в массив char или создать const char * для содержимого std::string, чтобы вы могли получить к нему доступ "Стиль C".

Если вы пытаетесь изменить содержимое std::string, тип std::string имеет все методы, чтобы сделать все, что вам может понадобиться сделать.

Если вы пытаетесь передать его некоторой функции, которая принимает char *, там std::string:: c_str().

Ответ 8

Это было бы лучше в качестве комментария к ответу bobobobo, но у меня нет репутации для этого. Он выполняет то же самое, но с лучшей практикой.

Хотя другие ответы полезны, если вам когда-либо понадобится преобразовать std::string в char* явно без const, const_cast - ваш друг.

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

Обратите внимание, что это будет не предоставить вам копию данных; он даст вам указатель на строку. Таким образом, если вы измените элемент chr, вы измените str.

Ответ 9

Для полноты, не забудьте std::string::copy().

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

str.copy(chrs, MAX);

std::string::copy() не завершается NUL. Если вам нужно обеспечить NUL-терминатор для использования в строковых функциях C:

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

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

Ответ 10

В качестве альтернативы вы можете использовать векторы, чтобы получить записываемый char *, как показано ниже:

//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  

Ответ 11

Вот еще одна надежная версия от 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

Ответ 12

Это также будет работать

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;  

Ответ 13

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

Ответ 14

Вы можете сделать это с помощью итератора.

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

Удачи.

Ответ 15

Безопасная версия orlp char * отвечает с помощью unique_ptr:

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