He escrito el siguiente fragmento de código pero no funciona. ¿Alguien puede ayudarme? ¿Dónde estoy equivocado?

char *xstrrev(char *string)
{
    int len=0,i=0;
    char *reverse;
    while(*string!='\0')
    {
        len++;
        string++;
    }
    len=len-1;
    while(len>=0)
    {
      *reverse=string[len];
       reverse++;
       len--;
    }
    *reverse='\0';
    return reverse; 
}

int main()
{
    char name[10];
    scanf("%s",name);
    printf("%s",xstrrev(name)); 
    return 0;
}

No puedo devolver una cadena completa en la función principal

-1
Kunal Verma 26 dic. 2016 a las 12:23

3 respuestas

La mejor respuesta

Tres problemas:

[1] reverse no apunta a un área de memoria válida.

[2] devolviendo reverse devolverá la dirección del último byte de la cadena reverse. por lo tanto, debe almacenar el inicio de reverse y devolver el inicio de reverse.

[3] string se analiza por completo al calcular la longitud, por lo que nuevamente, el inicio de la cadena original debe guardarse y utilizarse posteriormente

char *xstrrev(char *string)
{
    char *original_string = string;
    int len=0,i=0;
    //[1] char *reverse;
    while(*string!='\0')
    {
        len++;
        string++;
    }

    //[3] till here "string" is completely parsed, so it points to past the end.

    char *reverse = (char*)malloc(len + 1);
    char *reverse_to_be_returned = reverse;
    len=len-1;
    while(len>=0)
    {
        //[3] *reverse=string[len];
        *reverse = original_string[len]; 
        reverse++;
        len--;
    }
    *reverse='\0';
    //[2] return reverse; 
    return reverse_to_be_returned;
}
0
sameerkn 26 dic. 2016 a las 11:09

El problema comienza (y termina) con

  *reverse=string[len];

Donde reverse no se inicializa. Esto invoca comportamiento indefinido.

Debe inicializar reverse para que apunte a una ubicación de memoria válida antes de que pueda desreferenciar el puntero.

Dado que espera _volver_ la nueva _cadena_ de su función y usarla en la persona que llama, debe usar funciones de asignación de memoria, como malloc() para asignar memoria e inicializar reverse con el puntero devuelto, después de la comprobación de éxito de la llamada malloc(). También debe ocuparse de free() - la memoria asignada, una vez que haya terminado de usarla.

Después de eso, según su lógica, está haciendo reverse++; y al final, está devolviendo reverse, así que piense en el valor exacto que se devuelve. Está devolviendo un puntero al final de la cadena, no un puntero al inicio de la misma. Debe conservar una copia del inicio real de reverse y devolverla.

2
Sourav Ghosh 26 dic. 2016 a las 09:35

Debe asignar espacio para que char *reverse apunte. Esto se puede hacer con malloc o strdup.

Básicamente:

malloc() asigna la memoria solicitada en el montón y devuelve un puntero void* al final.

También debe verificar el puntero de retorno de cualquier llamada a malloc(), ya que a veces puede devolver NULL si sucede algo incorrecto.

También necesita free esta memoria solicitada al final, solo para cuidate.

Además, dado que está devolviendo un puntero, debe asegurarse de que apunte al comienzo de la cadena, en lugar de al final.

Su código puede verse así:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NAMESTRLEN 10

char *xstrrev(char *string);

int
main(void) {
    char name[NAMESTRLEN+1];
    char *result;

    printf("Enter string: ");
    scanf("%10s", name);

    result = xstrrev(name);
    printf("Reversed string = %s\n", result);

    free(result);

    return 0;
}

char
*xstrrev(char *string) {
    char *result;
    size_t slen, count = 0;
    int i;

    slen = strlen(string);

    result = malloc(slen+1); /* +1 for nullbyte */
    if (!result) {
        printf("Cannot allocate space for string.\n");
        exit(EXIT_FAILURE);
    }

    for (i = slen-1; i >= 0; i--) {
        result[count++] = string[i];
    }
    result[count] = '\0';

    return result;
}
0
RoadRunner - MSFT 26 dic. 2016 a las 10:11