convertir un char * a std :: string

262

Necesito usar un std::stringpara almacenar datos recuperados por fgets(). Para hacer esto, necesito convertir el char*valor de retorno de fgets()a std::stringa store en una matriz. ¿Cómo se puede hacer esto?

Jonathan Prior
fuente

Respuestas:

376

std::string tiene un constructor para esto:

const char *s = "Hello, World!";
std::string str(s);

Tenga en cuenta que esta construcción copia en profundidad la lista de caracteres en sy sno debe ser nullptr, o el comportamiento no está definido.

Jesse Beder
fuente
66
¿Qué pasará si es así?
Carson Myers
14
Standard dice que el parámetro constructor "no será un puntero nulo"; no especifica que se generen excepciones.
24
¿Es una copia superficial o profunda?
44
@pushkin No stres solo un nombre de variable. Podría ser cualquier cosa: S, abc, l, I, strHelloWorld. Obviamente, algunas opciones son mejores que otras. Pero para este ejemplo stres bastante aceptable.
Desilusionado
10
@Madhatter es una copia profunda. La asignación del puntero permanecerá y la cadena se convertirá en una nueva asignación.
moodboom
127

Si ya conoce el tamaño del char *, use esto en su lugar

char* data = ...;
int size = ...;
std::string myString(data, size);

Esto no usa strlen.

EDITAR: Si la variable de cadena ya existe, use asignar ():

std::string myString;
char* data = ...;
int size = ...;
myString.assign(data, size);
Eugene
fuente
1
Una especie de pregunta secundaria, Eugene. Si los datos no se rellenan hasta más adelante en la rutina, ¿cómo se inicializa myString? ¿Simplemente declara la variable myString cuando se llena?
IcedDante
2
int tamaño = strlen (datos);
Vlad
@vlad: la idea es que sepa que el tamaño de alguna otra fuente y / o datos no es una cadena en C (tiene nulos incrustados o no termina en un nulo). Si tiene una cadena en C, simplemente puede hacer myString = data; correrá strlen o equivalente para ti.
Eugene
1
@huseyintugrulbuyukisik Aún debe deshacerse de la memoria original de manera adecuada: std :: string copiará los bytes, no toma posesión.
Eugene
2
@ZackLee asignará nueva memoria para los bytes y los copiará todos allí, tan profundo como sea posible. Si desea potencial para una copia superficial, debe copiar una cadena std :: en otra. Entonces, algunas implementaciones podrían hacer una copia superficial, creo.
Eugene
30

La mayoría de las respuestas hablan sobre la construcción std::string .

Si ya está construido, solo use el operador de asignación .

std::string oString;
char* pStr;

... // Here allocate and get character string (e.g. using fgets as you mentioned)

oString = pStr; // This is it! It copies contents from pStr to oString
Atul
fuente
28

Necesito usar std :: string para almacenar los datos recuperados por fgets ().

¿Por qué usar fgets()cuando estás programando C ++? ¿Por qué no std::getline()?

Pablo
fuente
18

Pásalo a través del constructor:

const char* dat = "my string!";
std::string my_string( dat );

Puede usar la función string.c_str () para ir al otro lado:

std::string my_string("testing!");
const char* dat = my_string.c_str();
James Thompson
fuente
3
c_str()vuelveconst char*
Steve Jessop
1
a la derecha, no puede (no debería) modificar los datos en un std :: string a través de c_str (). Si tiene intención de cambiar los datos, entonces la secuencia de c de c_str () debe ser memcpy'd
Carson Myers
11
const char* charPointer = "Hello, World!\n";
std::string strFromChar;
strFromChar.append(charPointer);
std::cout<<strFromChar<<std::endl;

fuente
6
char* data;
stringstream myStreamString;
myStreamString << data;
string myString = myStreamString.str();
cout << myString << endl;
Presen
fuente
5

Me gustaría mencionar un nuevo método que utiliza el literal definido por el usuario s. Esto no es nuevo, pero será más común porque se agregó en la Biblioteca estándar de C ++ 14.

En gran medida superfluo en el caso general:

string mystring = "your string here"s;

Pero le permite usar auto, también con cadenas anchas:

auto mystring = U"your UTF-32 string here"s;

Y aquí es donde realmente brilla:

string suffix;
cin >> suffix;
string mystring = "mystring"s + suffix;
Erik van Velzen
fuente
2

He estado luchando con MSVC2005 para usar el std::string(char*)constructor como la respuesta mejor calificada. Como veo esta variante listada como # 4 en http://en.cppreference.com/w/cpp/string/basic_string/basic_string , siempre confiable , creo que incluso un compilador antiguo ofrece esto.

¡Me ha llevado tanto tiempo darme cuenta de que este constructor se niega absolutamente a coincidir (unsigned char*)como argumento! Recibí estos mensajes de error incomprensibles sobre la falla en la coincidencia con el std::stringtipo de argumento, que definitivamente no era lo que buscaba. Solo lanzar el argumento std::string((char*)ucharPtr)resolvió mi problema ... ¡duh!

usuario1564286
fuente
0
char* data;
std::string myString(data);
Daniel A. White
fuente
9
Esto dará como resultado un comportamiento indefinido.
1
Con solo estas dos líneas, datapermanece sin inicializar (vacío).
heltonbiker
1
Sin la "longitud" verdadera del puntero proporcionado, este código puede causar la pérdida de datos, su cadena std :: será "más corta" que el carácter original *
Andiana
0

No estoy seguro de por qué nadie además de Erik mencionó esto, pero de acuerdo con esta página , el operador de asignación funciona bien. No es necesario usar un constructor, .assign () o .append ().

std::string mystring;
mystring = "This is a test!";   // Assign C string to std:string directly
std::cout << mystring << '\n';
Vern Jensen
fuente
1
Parece que funciona funcionalmente, pero cuando hice esto, comencé a tener problemas con Valgrind que informaba que los bloques alcanzables al final del programa, que se originaban en un "nuevo" dentro de =(y +=). No parece suceder con literales como este, sino solo con char*cosas. La cuestión de si tales informes son en realidad fugas se discute aquí . Pero si cambié la asignación a destString = std::string(srcCharPtr);la valgrind, los informes de fugas desaparecerán. YMMV.
HostileFork dice que no confíes en SE
El comentario de HostileFork podría llevarlo a creer que construir una cadena a partir de un char * (como de fgets) hará que std :: string administre la vida útil de esta memoria. Sin embargo, éste no es el caso. Ver el estándar 21.4.2.7 y .9 Constructs an object of class basic_string and determines its initial string value from the array. Dice valor y nada sobre buffers o propiedad de punteros.
Erik van Velzen