Ayuda con revertir una cadena en C

Estoy tratando de revertir una cadena de caracteres en C

Esto es lo que tengo

void reverse(char str[]) { int i = 0; int length; // Get string length for (i = 0; str[i] != '\0' ; ++i) { length = i; } char reversed[1000]; int j; j = 0; // Reverse it for (j = 0; j < length ; ++j) { reversed[j] = str[length - j]; } } 

Sé que reversed contiene la cadena invertida, pero no estoy seguro de cómo modificar la str original sin descartar los datos que necesito.

Tampoco sé cómo configurar str en reversed sin hacer un bucle de nuevo .

¿Sería aceptable hacer otra …

  int m; m = 0; for (m = 0; m < length ; ++m) { str[j] = reversed[j]; } 

Por lo general, diría que muchos de estos bucles huelen, pero tampoco estoy familiarizado con el idioma, así que no estoy seguro …

Actualizar

Gracias por todas las respuestas, chicos, y aprecio las ediciones también!

Terminé yendo con esto …

 int main() { char str[] = "Reverse me!"; int length; for (length = 0; str[length] != '\0'; length++) { } printf("length => %d chars\n", length); int j, k; char c; for (j = 0, k = length - 1; j  %s\n", str); return 0; } 

Algunas cosas que ahora sé …

  • Hay un strlen() como en PHP. Sin embargo, aún no se ha discutido en el libro, además necesito familiarizarme con cadenas terminadas en nulo.
  • Un bucle for puede asignar y hacer varias cosas que están separadas por comas. ¡Nunca supe esto!

Así que preguntar valió la pena 🙂

Comentarios sobre su código:

 void reverse(char str[]) { int i = 0; int length; // Get string length for (i = 0; str[i] != '\0' ; ++i) { length = i; } 

En lugar de copiar la i a la longitud cada vez que puede esperar hasta el final.

 size_t len = 0; // size_t is an unsigned integer that is large enough to hold the sizes // of the biggest things you can have (32 bits on 32 bit computer, // 64 bits on a 64 bit computer) char * s = str; while (*s) { len++; s++; } 

Aunque el comstackdor probablemente podría hacer esta optimización para usted.

Sin embargo, debe saber que hay una función de cadena estándar strlen ( #include ) que medirá la longitud de una cadena de caracteres utilizando el mismo algoritmo general (busque el final) pero que generalmente está optimizado para el objective procesador.

 len = strlen(str); 

Su código de nuevo:

  char reversed[1000]; 

El uso de matrices grandes es bueno para aprender y ejemplos simples, pero también puede asignar memoria dinámicamente según el tamaño que ahora sabe que necesita. La función estándar para hacer esto es malloc que está en stdlib.h (también en malloc.h ). Sin embargo, la memoria asignada con esta función también debe liberarse.

 int * p = malloc( 8 * sizeof(int) ); // allocate an array of 8 ints /* ... work on p ... */ free(p); /* ... don't access the memory pointed to by p anymore ... */ p = 0; 

También hay otras funciones en la familia malloc. Hay calloc , que asigna memoria y borra lo establece en 0. También hay una función llamada strdup (que no está en el estándar C, pero está muy disponible en string.h) que toma una cadena y le asigna un duplicado. Es realmente justo:

 char * strdup(const char * str) { size_t len = strlen(str); char * s = malloc(len+1); if (!s) { return s; } return strcpy(s,str); // This could have been memcpy since you know the size // and memcpy might have been faster on many processors } 

Otra función de asignación de memoria útil es alloca (no en el estándar C, pero está disponible ampliamente disponible y existe una funcionalidad similar con matrices de longitud variable en C99). Es genial, pero funciona de manera diferente a malloc . Asigna memoria que solo se puede usar hasta que la función actual regrese porque esta memoria está asignada de la misma manera que la memoria para variables locales (de la stack).

Más de tu código:

  int j; j = 0; // Reverse it for (j = 0; j < length ; ++j) { reversed[j] = str[length - j]; } 

El código:

 void reverse_in_place(char * str, size_t len) { size_t i, j; for (i = 0, j = len - 1; i < j ; i++, j--) { char a = str[i]; char z = str[j]; str[i] = z; str[j] = a; } } 

Debería intercambiar el orden de la cadena sin hacer una copia de la misma. Para cuerdas con una longitud impar, no intentará intercambiar la charla central consigo misma.

Usted quiere hacer una reversión en el lugar . Aquí hay un algoritmo estándar:

 // taken from The C Programming Language // by Brian Kernighan and Dennis Ritchie (K&R) void reverse(char s[]) { int c, i, j; for (i = 0, j = strlen(s)-1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } } 

Tenga en cuenta que strlen reemplaza prácticamente su primer bucle original. Es una de las muchas rutinas estándar de manipulación de cadenas disponibles en string.h .

Ver también

  • Wikipedia / algoritmo in situ
  • Wikipedia / string.h
  • Wikipedia / C Standard Library

Puede usar cualquiera de los dos métodos a continuación, dependiendo de si se siente cómodo con los punteros o no. También valdrá la pena verlos uno al lado del otro cuando aprendas sobre los punteros para que puedas comprender mejor cómo se relacionan entre sí.

Este es un progtwig completo para propósitos de prueba:

 #include  #include  // The pointer version. void reverse1 (char *str) { char t; // Temporary char for swapping. char *s = str; // First character of string. char *e = &(s[strlen(s)-1]); // Last character of string. // Swap first and last character the move both pointers // towards each other. Stop when they meet or cross. while (s < e) { t = *s; *s++ = *e; *e-- = t; } } // The array version. void reverse2 (char *str) { char t; // Temporary char for swapping. int s = 0; // First character of string. int e = strlen(str)-1; // Last character of string. // Swap first and last character the move both pointers // towards each other. Stop when they meet or cross. while (s < e) { t = str[s]; str[s++] = str[e]; str[e--] = t; } } 

 int main (void) { char x[] = "This is a string for reversing."; printf ("Original: [%s]\n", x); reverse1 (x); printf ("Reversed: [%s]\n", x); reverse2 (x); printf (" Again: [%s]\n", x); return 0; } 

y la salida es:

 Original: [This is a string for reversing.] Reversed: [.gnisrever rof gnirts a si sihT] Again: [This is a string for reversing.] 

Invirtiendo una cadena en C usando punteros

 #include char *srcptr = "Hello!"; char *destptr; unsigned int length = 0; void main(void) { while(*(ptr++) != '\0') { length++; } //at the end of while loop, pointer points to end of string while(length--) { *destptr++ = *ptr--; } //append null at the end *destptr = '\0'; printf("%s",ptr); }