std :: string to char * - PullRequest
       41

std :: string to char *

285 голосов
/ 08 сентября 2011

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

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

Результат: «ошибка: невозможно преобразовать ‘std :: string’ в ‘char’ ... ».

Какие есть способы сделать это?

Ответы [ 16 ]

592 голосов
/ 08 сентября 2011

Он не будет автоматически конвертироваться (слава богу).Вам нужно будет использовать метод 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;

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

std::vector<char> cstr(str.c_str(), str.c_str() + str.size() + 1);
130 голосов
/ 12 мая 2013

Подробнее здесь и здесь , но вы можете использовать

string str = "some string" ;
char *cstr = &str[0u];
37 голосов
/ 08 сентября 2011

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

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

и позже:

free(chr); 

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

21 голосов
/ 08 сентября 2011

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

Пожалуйста, не используйте необработанные char*.

std::string str = "string";
std::vector<char> chars(str.c_str(), str.c_str() + str.size() + 1u);
// use &chars[0] as a char*
13 голосов
/ 08 сентября 2011
  • Если вам просто нужна строка в стиле 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
10 голосов
/ 18 февраля 2017

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

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

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

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

6 голосов
/ 08 сентября 2011

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

std::string str = "string";
const char* chr = str.c_str();
5 голосов
/ 08 сентября 2011

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

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

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

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

4 голосов
/ 16 декабря 2015

Вот еще одна надежная версия из 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
4 голосов
/ 12 мая 2013

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

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

str.copy(chrs, MAX);

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

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

memset(chrs, '\0', MAX);
str.copy(chrs, MAX-1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...