Я хочу преобразовать std :: string в тип данных char * или char [] .
std::string str = "string";
char* chr = str;
Результат: «ошибка: невозможно преобразовать« std :: string »в« char »...» .
Какие методы доступны для этого?
Он не будет автоматически конвертироваться (слава богу). Вы должны будете использовать метод, 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);
c_str
безумия.vector
был придуман именно как оболочка для динамических массивов, поэтому его использование в лучшем случае кажется упущенной возможностью, а в худшем - нарушением духа C ++.std::string
это автоматически преобразует), а затем объясняю, что он должен использовать, с коротким примером кода. Забегая вперед, я также объясню некоторые побочные эффекты использования этой функции, одна из которых заключается в том, что вы не можете редактировать возвращаемую строкуc_str()
. Вы ошибочно видите мои короткие примеры как реальный код для решения проблем, а это не так.std::vector<char>
).Подробнее здесь и здесь, но вы можете использовать
источник
Если бы мне нужна изменяемая сырая копия строкового содержимого c ++, я бы сделал это:
и позже:
Так почему бы мне не поиграться с std :: vector или new [] как кто-либо еще? Потому что, когда мне нужна изменяемая необработанная строка char * в стиле C, то, потому что я хочу вызвать код C, который изменяет строку, а код C освобождает вещи с помощью free () и выделяет с помощью malloc () (strdup использует malloc) . Поэтому, если я передам свою необработанную строку какой-либо функции X, написанной на C, у нее может быть ограничение на аргумент, который она должна разместить в куче (например, если функция может захотеть вызвать realloc для параметра). Но очень маловероятно, что он ожидал бы аргумент, выделенный (каким-то образом переопределенным пользователем) new []!
источник
strdup
.(Этот ответ относится только к C ++ 98.)
Пожалуйста, не используйте сырье
char*
.источник
vector<char>(str.c_str(), str.c_str() + str.size() + 1)
, не назначая указатель на символ временный?std::basic_string<>::c_str()
действует до тех пор, пока неstring
будет изменено или уничтожено. Это также подразумевает, что оно возвращает то же значение при последующих вызовах, еслиstring
оно не изменено.vector
. И если бы нужно было написать код, исключающий исключения, без механизма RAII (т. Е. С использованием необработанных указателей), сложность кода была бы намного выше, чем у этого простого однострочного.vector
имеет огромное количество накладных расходов и сложности. Если вы требуете, чтобы у вас был изменяемый массив символов, то фактически вектор символов в значительной степени является идеальной оболочкой C ++. Если ваше требование на самом деле просто требует указателя const-char, просто используйтеc_str()
и все готово.Если вам нужна строка в стиле C, представляющая тот же контент:
Если вам нужна строка в стиле C с новым содержимым, одним из способов (учитывая, что вы не знаете размер строки во время компиляции) является динамическое распределение:
Не забудь об
delete[]
этом позже.Если вам нужен статически размещенный массив ограниченной длины:
std::string
неявно преобразуется в эти типы по той простой причине, что для этого обычно требуется запах проекта. Убедитесь, что вам это действительно нужно.Если вам определенно нужен
char*
, вероятно , лучший способ:источник
&str.front(), &str.back()
(которых нет в C ++ 03) вместо более распространенныхstr.begin()
иstr.end()
?str.begin()
, или дажеstd::begin(str)
, итератор типа? Я не верю,string
что обязан быть в смежных воспоминанияхvector
, или это так?&back() + 1
, а не&back()
Это было бы лучше в качестве комментария к ответу Бобобо, но у меня нет представителя для этого. Это выполняет то же самое, но с лучшими практиками.
Хотя другие ответы полезны, если вам когда-либо понадобится явно преобразовать
std::string
вchar*
const,const_cast
это ваш друг.Обратите внимание, что это не даст вам копию данных; это даст вам указатель на строку. Таким образом, если вы измените элемент
chr
, вы изменитеstr
.источник
Предполагая, что вам просто нужна строка в стиле C для передачи в качестве входных данных:
источник
Чтобы быть строго педантичным, вы не можете «преобразовать std :: string в тип данных char * или char []».
Как показали другие ответы, вы можете скопировать содержимое std :: string в массив char или сделать const char * для содержимого std :: string, чтобы получить к нему доступ в стиле «C» ,
Если вы пытаетесь изменить содержимое std :: string, тип std :: string имеет все методы, чтобы сделать все, что вам может понадобиться.
Если вы пытаетесь передать его какой-то функции, которая принимает char *, есть std :: string :: c_str ().
источник
Вот еще одна надежная версия от
Protocol Buffer
источник
if (str[str.length()-1] != 0) str.push_back(0)
Преобразование в стиле ООП
converter.hpp
converter.cpp
использование
источник
Ради полноты не забывайте
std::string::copy()
.std::string::copy()
не NUL прекращать. Если вам нужно обеспечить терминатор NUL для использования в строковых функциях C:источник
Вы можете сделать это с помощью итератора.
Удачи.
источник
Безопасная версия ответа char * orlp с использованием unique_ptr:
источник
Чтобы получить
const char *
изstd::string
использованияc_str()
функцию-член:Чтобы получить неконстантный
char *
объект из,std::string
вы можете использоватьdata()
функцию-член, которая возвращает неконстантный указатель начиная с C ++ 17:Для более старых версий языка вы можете использовать конструкцию диапазона, чтобы скопировать строку в вектор, из которого можно получить неконстантный указатель:
Но учтите, что это не позволит вам изменить строку, содержащуюся в этом
str
, только данные копии могут быть изменены таким образом. Обратите внимание, что это особенно важно в старых версиях языка, чтобы использоватьc_str()
здесь, потому что тогдаstd::string
не было гарантировано, что будет завершено нулем, пока неc_str()
был вызван.источник
источник
Кроме того, вы можете использовать векторы, чтобы получить записываемый символ *, как показано ниже;
источник
Это тоже будет работать
источник