2011-02-19 17 views
8

Estoy tratando de cortar los últimos 4 caracteres de una matriz de caracteres y probé el método que utiliza python sin éxito;División de matrices en C++

char *charone = (char*)("I need the last four") 
char *chartwo = charone[-4:] 

cout << chartwo << endl; 

Me gustaría que este código vuelva;

four 

pero C/C++ no parece ser tan fácil ...

¿Dónde podría encontrar una alternativa sencilla que devolverá los últimos 4 caracteres de una matriz de caracteres en otra matriz de caracteres?

+0

¿Por qué echas? ¿Es porque estás usando gcc y te da una advertencia? –

+0

Sí XP, y cuando no lo hago obtengo una falla de segmentación generalmente. – MetaDark

+1

Derecha, en C++ los literales de cadena son const char, por lo que debe usar un const char * para señalarlo. Eso es probablemente lo que el compilador también le dice. –

Respuesta

12

Probar:

int len = strlen(charone); 
char *chartwo = charone + (len < 4 ? 0 : len - 4); 

En C++, puede reemplazar eso con:

char* chartwo = charone + (std::max)(strlen(charone), 4) - 4; 

El código utiliza una propiedad especial de cadenas de C que sólo funciona para picar fuera el comienzo de una cadena.

+0

Su método es más robusto, pero el mío es una constante en tiempo de compilación. ;-) Entonces, pros y contras de cada uno, supongo. :-) –

+0

La optimización del compilador @Chris debería hacerlos iguales. – alternative

+0

@mathepic: La versión de la que él habla probablemente sea la que usó 16 como desplazamiento (suponiendo que la longitud de la cuerda fuera 20) y no calculó la longitud de la cuerda; el compilador podría evaluar 'strlen' en una cadena constante, pero no sé si hay alguno. –

1

Esto se hace:

char* chartwo = charone + 16; 
+1

Mis matrices de caracteres serán dinámicas, por lo que probablemente no funcionen – MetaDark

7

En primer lugar, vamos a eliminar la conversión en desuso:

char const *charone = "I need the last four"; 

Las matrices no son valores de primera clase en C++, y que no son compatibles con el corte en lonchas. Sin embargo, al igual que el personaje anterior apunta al primer elemento de la matriz, puede señalar cualquier otro elemento. Los punteros se usan con caracteres para hacer cadenas de estilo C: el carácter apuntado hacia arriba hasta que un carácter nulo es el contenido de la cadena. Debido a que los caracteres que desea están en el extremo de la cadena actual (Charone), puede apuntar a la "f":

char const *chartwo = charone + 16; 

O, para manejar los valores de cadena arbitrarias:

char const *charone = "from this arbitrary string value, I need the last four"; 
int charone_len = strlen(charone); 
assert(charone_len >= 4); // Or other error-checking. 
char const *chartwo = charone + charone_len - 4; 

O, porque estás usando C++:

std::string one = "from this arbitrary string value, I need the last four"; 
assert(one.size() >= 4); // Or other error-checking, since one.size() - 4 
// might underflow (size_type is unsigned). 
std::string two = one.substr(one.size() - 4); 

// To mimic Python's [-4:] meaning "up to the last four": 
std::string three = one.substr(one.size() < 4 ? 0 : one.size() - 4); 
// E.g. if one == "ab", then three == "ab". 

En particular, cabe destacar que std :: string le da distintos valores, por lo que la modificación de alguna de las cadenas no modificar el otro como sucedería s con punteros.

3

Si usted está buscando para acceder solo brevemente los cuatro últimos caracteres, entonces algo así como

char* chartwo = charone + (strlen(charone) - 4); 

va a estar bien (más algo de comprobación de errores).

Pero si desea replicar la funcionalidad pitón, que se necesitan para copia los últimos cuatro caracteres. Nuevamente, use strlen para obtener la longitud (o guárdela en algún lugar de antemano), y luego use strcpy (o probablemente una mejor función stl que tenga la misma función). algo así como ...

char chartwo[5]; 
strcpy(chartwo, charone + strlen(charone) - 4); 

(Nota: Si no copiar, entonces no se puede Charone libre hasta que termine de usar chartwo.Además, si no copias, entonces si cambias a Charone más tarde, Chartwo también cambiará. Si eso está bien, entonces seguro, solo apunte a la compensación.)

+1

Es un buen punto sobre cómo copiar, sin embargo, no olvide asignar espacio para que Chartwo apunte. Deje el ", 4" (que es un error para strcpy) ya que sabemos que estamos copiando el nulo de terminación (y tenga cuidado de terminar nulo correctamente con strncpy si necesita copiar desde el medio). –

+0

gracias, escribí esto rápido ... ¿es eso mejor? – jmilloy

+0

Mejor, pero chartwo necesita una longitud de 5. :) –

5

C++ y Python son muy diferentes. C++ no tiene recursos incorporados de cadenas similares a Python, pero su Standard Template Library tiene un práctico tipo std::string, que debe tener en cuenta.

1

array rebanar en C++:

array<char, 13> msg = {"Hello world!"}; 
array<char, 6> part = {"world"}; 

// this line generates no instructions and does not copy data 
// It just tells the compiler how to interpret the bits 
array<char, 5>& myslice = *reinterpret_cast<array<char,5>*>(&msg[6]); 

// now they are the same length and we can compare them 
if(myslice == part) 
    cout<< "huzzah"; 

Esta es sólo una de las emamples donde el corte en lonchas es ventajosa

he hecho una pequeña biblioteca que hace esto con tiempo de compilación limita los controles en https://github.com/Erikvv/array-slicing-cpp