с std::string в char*

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

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

результаты: "ошибка: не удается преобразовать' std:: string’ в ‘char’ ...".

какие методы есть для этого?

15 ответов


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

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

string str = "some string" ;
char *cstr = &str[0u];

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

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

и затем:

free(chr); 

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


(этот ответ относится только к C++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*

  • если вы просто хотите строку в стиле 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()] = '';
    

    не забудьте 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

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

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

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

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


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

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

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

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

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

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


ради полноты, не забывайте std::string::copy().

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

str.copy(chrs, MAX);

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

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

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

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

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

кроме того, вы можете использовать векторы для получения записываемого символа*, как показано ниже;

//this handles memory manipulations and is more convenient
string str;
vector <char> writable (str.begin (), str.end) ;
writable .push_back (''); 
char* cstring = &writable[0] //or &*writable.begin () 

//Goodluck  

вы можете сделать это с помощью iterator.

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

удачи.


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

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;  

безопасная версия orlp's char * ответ с использованием unique_ptr:

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