es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Reducir el tamaño de una cadena

(disclaimer: this is not a complete exercise because I have to finish it, but error occurred in this part of code)

Hice este ejercicio para practicar la asignación de memoria.

crear una función que tome una URL (una cadena C) y devuelva el nombre del sitio web (con “www.” y con la extensión).
por ejemplo, dado el enlace de Wikipedia, “http://www.wikipedia.org/”, tiene que devolver solo “www.wikipedia.org” en otra cadena (asignada dinámicamente en el montón).

Esto es lo que he hecho hasta ahora:
hacer un bucle for y cuando “i” sea mayor que 6, comenzar a copiar cada carácter en otra cadena hasta que se alcance “/”.
Necesito asignar memoria a la otra cadena y luego reasignarla.

Aquí está mi intento hasta ahora:

char *read_website(const char *url) {
    char *str = malloc(sizeof(char)); 
    if (str == NULL) {
        exit(1); 
    }
    for (unsigned int i = 0; url[i] != "/" && i > 6; ++i) {
        if (i <= 6) {
            continue; 
        }
        char* s = realloc(str, sizeof(char) + 1); 
        if (s == NULL) {
            exit(1); 
        }
        *str = *s; 
    }
    return str; 
}

int main(void) {
    char s[] = "http://www.wikipedia.org/"; 
    char *str = read_website(s); 
    return 0; 
}

(1) al depurar línea por línea, me he dado cuenta de que el programa termina una vez que se alcanza el bucle for.

(2) otra cosa: elegí crear otro puntero cuando usé realloc, porque tengo que verificar si hay alguna fuga de memoria. ¿Es una buena práctica? ¿O debería haber hecho algo diferente?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    (1) La condición del bucle for es incorrecta. El operador debería ser < en lugar de >. La condición correcta es url[i] != '/' && i < strlen(url). Además, falta la copia de caracteres en la nueva cadena dentro del bucle. Podemos utilizar la función strncat() para agregar cada carácter a la nueva cadena. Además, el tamaño de la nueva cadena debería asignarse dinámicamente con realloc() según la longitud de la subcadena extraída, no con sizeof(char) + 1. Aquí tienes una versión corregida de la función:

    char* leer_sitio_web(const char* url) {
        char* str = NULL;
        size_t len = 0;
        for (size_t i = 0; url[i] != '/' && i < strlen(url); ++i) {
            if (i < 7) { // omitir "http://"
                continue;
            }
            char* s = realloc(str, len + 2); // asignar 1 byte más para el terminador nulo
            if (s == NULL) {
                free(str);
                return NULL;
            }
            str = s;
            strncat(str, &url[i], 1);
            len++;
        }
        return str;
    }
    

    Ten en cuenta que la función debería devolver NULL si la asignación de memoria falla.

    (2) Es una buena práctica utilizar un puntero temporal con realloc() para almacenar la nueva dirección devuelta por la función. Esto te permite verificar si la asignación falló antes de actualizar el puntero original. Sin embargo, en lugar de copiar el valor del nuevo puntero al puntero original con *str = *s, simplemente debes actualizar el valor del puntero original con str = s. De esta manera, puedes realizar un seguimiento de la nueva dirección en caso de una reasignación exitosa.

Comments are closed.