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?

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.


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);

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

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()?


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();

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;

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

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;

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!


0
char* data;
std::string myString(data);

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';

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.