Quiero convertir un std :: string en un tipo de datos char * o char [] .
std::string str = "string";
char* chr = str;
Resulta en: "error: no se puede convertir 'std :: string' a 'char' ..." .
¿Qué métodos hay disponibles para hacer esto?
No se convertirá automáticamente (gracias a Dios). Tendrá que usar el método c_str()
para obtener la versión de cadena C.
std::string str = "string";
const char *cstr = str.c_str();
Tenga en cuenta que devuelve a const char *
; no puede cambiar la cadena de estilo C devuelta por c_str()
. Si desea procesarlo, primero deberá copiarlo:
std::string str = "string";
char *cstr = new char[str.length() + 1];
strcpy(cstr, str.c_str());
// do stuff
delete [] cstr;
O en C ++ moderno:
std::vector<char> cstr(str.c_str(), str.c_str() + str.size() + 1);
c_str
locura por completo.vector
fue inventado precisamente como un contenedor para matrices dinámicas, por lo que no usarlo parece una oportunidad perdida en el mejor de los casos, y en el peor de los casos, viola el espíritu de C ++.std::string
se convertiría automáticamente) y luego explico lo que debería usar, con un ejemplo de código corto. Mirando hacia el futuro, también explico algunos efectos secundarios del uso de esta función, de los cuales uno no puede editar la cadena devuelta porc_str()
. Usted ve erróneamente mis ejemplos breves como un código de resolución de problemas real, que no lo es.std::vector<char>
).Más detalles aquí , y aquí, pero puedes usar
fuente
Si necesitara una copia cruda mutable del contenido de la cadena de c ++, entonces haría esto:
y después:
Entonces, ¿por qué no juego con std :: vector o new [] como cualquier otra persona? Porque cuando necesito una cadena char * sin procesar de estilo C mutable, entonces porque quiero llamar al código C que cambia la cadena y el código C desasigna cosas con free () y asigna malloc () (strdup usa malloc) . Entonces, si paso mi cadena sin procesar a alguna función X escrita en C , podría tener una restricción en su argumento de que tiene que asignarse en el montón (por ejemplo, si la función podría llamar a realloc en el parámetro). ¡Pero es muy poco probable que espere un argumento asignado con (algunos redefinidos por el usuario) nuevo []!
fuente
strdup
es.(Esta respuesta se aplica solo a C ++ 98).
Por favor, no uses un crudo
char*
.fuente
vector<char>(str.c_str(), str.c_str() + str.size() + 1)
, sin asignar el puntero a un carácter temporal?std::basic_string<>::c_str()
es válido hasta questring
se cambie o se destruya. Esto también implica que devuelve el mismo valor en llamadas posteriores siempre questring
no se modifique.vector
de esta manera. Y si uno escribiera código seguro de excepción sin un mecanismo RAII (es decir, utilizando punteros sin formato), la complejidad del código sería mucho mayor que esta simple línea.vector
tiene una gran cantidad de gastos generales y complejidad. Si su requisito es que tenga una matriz de caracteres mutable , entonces, de hecho, un vector de caracteres es prácticamente el contenedor ideal de C ++. Si su requerimiento realmente solo requiere un puntero const-char, entonces simplemente usec_str()
y ya está.Si solo desea una cadena de estilo C que represente el mismo contenido:
Si desea una cadena de estilo C con nuevos contenidos, una forma (dado que no conoce el tamaño de la cadena en tiempo de compilación) es la asignación dinámica:
No lo olvides
delete[]
más tarde.Si desea una matriz de longitud limitada estáticamente asignada:
std::string
no se convierte implícitamente a estos tipos por la simple razón de que la necesidad de hacer esto suele ser un olor a diseño. Asegúrate de que realmente necesitas.Si definitivamente necesita un
char*
, la mejor manera es probablemente:fuente
&str.front(), &str.back()
(que no están presentes en C ++ 03) en lugar de los más comunesstr.begin()
ystr.end()
?str.begin()
, o inclusostd::begin(str)
, como un iterador? No creo questring
tenga ninguna obligación de estar en memoria contiguavector
, ¿o sí?&back() + 1
, no&back()
Esto sería mejor como un comentario sobre la respuesta de bobobobo, pero no tengo el representante para eso. Logra lo mismo pero con mejores prácticas.
A pesar de las otras respuestas son útiles, si alguna vez necesita para convertir
std::string
achar*
forma explícita y sin const,const_cast
es su amigo.Tenga en cuenta que esto no le dará una copia de los datos; le dará un puntero a la cadena. Por lo tanto, si modifica un elemento de
chr
, lo modificarástr
.fuente
Suponiendo que solo necesita una cadena de estilo C para pasar como entrada:
fuente
Para ser estrictamente pedante, no puede "convertir una cadena std :: en un tipo de datos char * o char []".
Como han mostrado las otras respuestas, puede copiar el contenido de std :: string a una matriz de caracteres, o hacer un const char * al contenido de std :: string para que pueda acceder a él en un "estilo C" .
Si está intentando cambiar el contenido de std :: string, el tipo std :: string tiene todos los métodos para hacer cualquier cosa que pueda necesitar.
Si está tratando de pasarlo a alguna función que toma un char *, hay std :: string :: c_str ().
fuente
Aquí hay una versión más robusta de
Protocol Buffer
fuente
if (str[str.length()-1] != 0) str.push_back(0)
Conversión en estilo OOP
converter.hpp
converter.cpp
uso
fuente
Por completo, no lo olvides
std::string::copy()
.std::string::copy()
no termina NUL. Si necesita asegurar un terminador NUL para usar en funciones de cadena C:fuente
Puedes hacerlo usando iterador.
Buena suerte.
fuente
Una versión segura de la respuesta char * de orlp usando unique_ptr:
fuente
Para obtener un
const char *
de unstd::string
uso de lac_str()
función miembro:Para obtener un no constante
char *
de unstd::string
puede usar ladata()
función miembro que devuelve un puntero no constante desde C ++ 17:Para versiones anteriores del lenguaje, puede usar la construcción de rango para copiar la cadena en un vector del que se puede obtener un puntero sin constante:
Pero tenga en cuenta que esto no le permitirá modificar la cadena contenida
str
, solo los datos de la copia se pueden cambiar de esta manera. Tenga en cuenta que es especialmente importante en versiones anteriores del lenguaje usarc_str()
aquí porque en aquel entoncesstd::string
no se garantizaba que se anulara hasta quec_str()
se llamara.fuente
fuente
Alternativamente, puede usar vectores para obtener un carácter de escritura * como se muestra a continuación;
fuente
Esto también funcionará
fuente