2011-01-14 13 views
32

Si la matriz fue terminada en nulo esto sería bastante sencillo:copia no terminada en nulo matriz de caracteres sin signo a std :: string

unsigned char u_array[4] = { 'a', 's', 'd', '\0' }; 
std::string str = reinterpret_cast<char*>(u_array); 
std::cout << "-> " << str << std::endl; 

Sin embargo, me pregunto ¿cuál es la forma más adecuada de copiar un matriz de caracteres no terminada en nulo sin signo, como el siguiente:

unsigned char u_array[4] = { 'a', 's', 'd', 'f' }; 

en un std::string.

¿Hay alguna manera de hacerlo sin iterar sobre matriz de caracteres sin signo?

Gracias a todos.

Respuesta

36

std::string tiene una constructor que toma un par de iteradores y unsigned char se puede convertir (en una manera definida aplicación) para char por lo que este funciona. No es necesario un reinterpret_cast.

unsigned char u_array[4] = { 'a', 's', 'd', 'f' }; 

#include <string> 
#include <iostream> 
#include <ostream> 

int main() 
{ 
    std::string str(u_array, u_array + sizeof u_array/sizeof u_array[0]); 
    std::cout << str << std::endl; 
    return 0; 
} 

Por supuesto una función de plantilla "tamaño de la matriz" es más robusto que el cálculo sizeof.

+0

Convirtiendo 'unsigned char *' en 'char *' aquí, tienes que hacer 'reinterpret_cast '. –

+1

@VladLazarenko: Pero no quiero hacer esa conversión. –

+0

@Charles: Entonces su código no se compilará a menos que cambie el tipo predeterminado para char a unsigned en la configuración del compilador;) –

3

std :: string tiene un método llamado assign. Puede usar un char * y un tamaño.

http://www.cplusplus.com/reference/string/string/assign/

+2

También tiene un constructor que toma el puntero y el tamaño de char. En aquellos casos en los que aún no tenga una instancia de cadena, tendrá sentido usar constructor. –

+0

El problema con esta situación es que usted no sabe cuántos bytes ocupa su cadena, y si hacer .c_str() le dará una cadena c válida o no. –

12

Bueno, al parecer std :: string tiene un constructor que podría ser utilizado en este caso:

std::string str(reinterpret_cast<char*>(u_array), 4); 
+1

Más de pensamiento ideológico, pero sería mejor no desechar la constness de matriz. Además, tomar tamaño de él en lugar de '' 4 'propenso a errores de codificación difícil. –

0

Se puede crear un puntero que apunta al carácter del primer carácter, y otro que apunta a uno pasado, y construye usando esos dos punteros como iteradores. Por lo tanto:

std::string str(&u_array[0], &u_array[0] + 4); 
+1

Esto es propenso a errores ya que el tamaño de la matriz puede cambiar, y puede olvidarse fácilmente de reemplazar su '4' con un nuevo valor. Además, no tiene sentido hacer '& u_array [0]', es equivalente a 'u_array', que es mucho menos tipeo. –

0

Probar:

std::string str; 
str.resize(4); 
std::copy(u_array, u_array+4, str.begin()); 
2

Se puede usar esta std::string constructor:

string (const char * s, size_t n); 

por lo que en el ejemplo:

std::string str(u_array, 4); 
+0

Puedes hacerlo mejor haciendo 'sizeof (u_array)'. O incluso mejor: 'sizeof (u_array)/sizeof (u_array [0])', que funcionará para tipos de datos cuyo tamaño es mayor que 1 byte. –

1

Esto debe hacerlo:

std::string s(u_array, u_array+sizeof(u_array)/sizeof(u_array[0])); 
+0

u_array es de tipo unsigned char, y 'std :: string' constructor toma' const char * ', por lo que ni siquiera se compilará. –

+0

@Vlad Lazarenko: No, como he comprobado debería estar bien. – cpx

+0

@Dave, el tipo predeterminado para char está firmado, no sin firmar, y no puede convertir implícitamente uno en otro. Tu compilador trata 'char' como' unsigned' o tiene errores. En cualquier caso, la solución genérica no debe basarse en estos detalles y usar una conversión explícita. Puede verificar esto con Comeau en línea o algo así, no funciona. –

3

Cuando se construye una cadena sin especificar su tamaño, el constructor se iterar sobre una matriz de un personaje y buscarse un terminador nulo, que es '\0' carácter. Si usted no tiene ese carácter, hay que especificar la longitud de forma explícita, por ejemplo:

// --*-- C++ --*-- 

#include <string> 
#include <iostream> 


int 
main() 
{ 
    unsigned char u_array[4] = { 'a', 's', 'd', 'f' }; 
    std::string str (reinterpret_cast<const char *> (u_array), 
        sizeof (u_array)/sizeof (u_array[0])); 
    std::cout << "-> " << str << std::endl; 
} 
0

std :: string tiene un constructor teniendo una matriz de char y una longitud.

unsigned char u_array[4] = { 'a', 's', 'd', 'f' }; 
std::string str(reinterpret_cast<char*>(u_array), sizeo(u_array)); 
0

Ew, why the cast?

std::string str(u_array, u_array + sizeof(u_array)); 

Hecho.

0

Hay una siendo un problema cuando la cadena en sí contiene un carácter nulo e intenta imprimir posteriormente la cadena:

char c_array[4] = { 'a', 's', 'd', 0 }; 

std::string toto(array,4); 
cout << toto << endl; //outputs a 3 chars and a NULL char 

Sin embargo ....

cout << toto.c_str() << endl; //will only print 3 chars. 

Sus tiempos como estos cuando solo quiere deshacerse de la ternura y usar desnudo C.

Cuestiones relacionadas