[ Foro de C ]

Comportamiento extraño de variable int

28-Jul-2015 17:02
Sergio González Taboada
1 Respuestas

Muy buenas a todos. Vereis, estaba tratando de realizar el ejercicio propuesto 5.2.2.1 de programación en C y me he encontrado con un problema que no logro solucionar.

Buscando otros programas para el mimsmo ejercicio que otras personas fueron publicando en este mismo foro, me he dado cuenta de que igual mi forma de estructurar el programa no es la más correcta, e igual para elaborar el menú era más apropiado usar switch y no condicionales con if... . Agradecería enormemente que alguien fuese crítico con la forma de estructurar mi ejercicio, pues estoy aprendiendo de forma totalmente autodidacta y temo adoptar formas erróneas.

En mi programa creo una variable que uso para registrar el número de canciones que se memorizaron en total. Le puse el nombre de "cancionesMem" y la inicializo con valor 0.
El valor de esta variable la incremento una y cada vez que memorizo una nueva canción.

A medida que avanzo el programa y voy guardando canciones, "cancionesMem" va incrementando sin ningún problema, hasta que llamo a la opción del menú "buscar", momento en el que "cancionesMem" pasa a adoptar el valor 0!!!
No logro entender en qué momento se le da a esa variable el valor cero. Le di un montón de vueltas y no logro entenderlo.
Si alguien me puede ayudar, estaría agradecido.

Un saludo.


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

int main()
{
    
    /*Se declaran las variables que se puedan necesitar durante el programa*/
    
    
    int i;
    int cancionesMem=0;         //Almacena el número de canciones ya guardadas en memoria
    char escrituraLectura[6];   //Variable usada para determinar si el usuario quiere guardar o ver canciones almacenadas
    char cancionBusca[40];
    
    
    
    /*Se declara la estructura*/
    
    struct {
        char artista[40];
        char titulo[40];
        char cancion[100][50];  //Array para almacenar hasta 100 canciones de 50 caracteres de longitud
        float duracion;
        int tamano;
    }datosMP3;
    
    
    
    /*Se introducen los datos del artista y album*/
    
    printf("A continuación introduce los datos del album \n");
    
    /* Se leen los datos referentes al album*/
    printf("Artista: \n");
    gets(datosMP3.artista);
    
    printf("Titulo: \n");
    gets(datosMP3.titulo);
    
    printf("Duración: \n");
    scanf("%f", &datosMP3.duracion);
    
    printf("tamaño: \n");
    scanf("%d", &datosMP3.tamano);
    
    getchar(); //Absorbe el enter
    
    
    printf("El número de canciones memorizadas es: %d (Antes de do)\n", cancionesMem); //Esta línea la uso para monitorizar
    
    
    //Se inicia el programa en bucle con do... while
    
    do{
    
    printf("- Si desea añadir una canción nueva teclee 'nuevo' \n");
    printf("- si desea buscar una canción teclee 'buscar' \n");
    printf("- si desea mostrar todas las canciones teclee 'todas' \n");
    printf("- Si desea salir de la aplicación teclee 'salir' \n");
    gets(escrituraLectura);
    
        
    /*Para introducir NUEVA cancion*/
    
    if(strcmp(escrituraLectura, "nuevo")==0){       //Si ha escogido tema nuevo: sucede todo lo siguiente
        printf("Introduce una nueva canción: \n");
        gets(datosMP3.cancion[cancionesMem]);
        cancionesMem=cancionesMem+1;            //Almacenamos una canción más, aumentamos en +1 el indicador de canciones guardadas
        printf("El número de canciones memorizadas es: %d \n", cancionesMem);
    }
        
        
    /*Para BUSCAR una canción en memoria*/
    
    if(strcmp(escrituraLectura, "buscar")==0){
        printf("Introduce el nombre de la canción que deseas buscar: \n");
        
        printf("El número de canciones memorizadas es: %d \n", cancionesMem);
        
        gets(cancionBusca);
    
        
        for (i=0 ; i<=cancionesMem-1; i++){ //-1, porque a cancionesMem todavía no se le ha asignado un nuevo título
            
        if (strcmp(cancionBusca, datosMP3.cancion[i])==0){  //Si encuentra la canción, hace todo lo que sigue
            
            printf("La canción seleccionada se encuentra en memoria \n");
            printf("%s \n", datosMP3.artista);
            printf("%s \n", datosMP3.titulo);
            printf("%s \n", datosMP3.cancion[i]);
            printf("%3.2f mins \n", datosMP3.duracion);
            printf("%d kb \n", datosMP3.tamano);
            
            printf("El número de canciones memorizadas es: %d \n", cancionesMem);
            
        }
        }//corchete cierre del for
    }//corchete del if de busqueda de canciones
    
    
        
    /*Para mostrar TODAS las canciones*/
    
    if(strcmp(escrituraLectura, "todas")==0){
        printf("El listado completo de canciones es el siguiente: \n");
        printf("%s \n", datosMP3.artista);
        printf("%s \n", datosMP3.titulo);
        printf("%3.2f mins \n", datosMP3.duracion);
        printf("%d kb \n", datosMP3.tamano);
        
        for (i=0 ; i<=cancionesMem-1; i++){           //Se imprimen todas las canciones
            printf("%s \n", datosMP3.cancion[i]);
        }
        printf("El número de canciones memorizadas es: %d \n", cancionesMem);
    }
        
    
        

    }while (strcmp(escrituraLectura, "salir")!=0);
 
}




31-Jul-2015 12:50
Nacho Cabanes (+83)

Hasta donde te sea posible, incluye el enunciado del ejercicio al que te refieres, porque los cursos van evolucionando y puede cambiar su numeración. Por ejemplo, en la versión online del curso de C que se puede leer en estas páginas, el ejercicio del apartado 5.2.2 es

- Un programa que pida al usuario que introduzca una palabra, cambie su primera letra por una "A" y muestre la palabra resultante.

Claramente, ese no es tu ejercicio.

Veo que tu programa almacena distintos nombres de canciones, si bien todas ellas tienen un único artista, título, duración y tamaño, lo que suena a que algo no está bien del todo. También provoca algún warning al compilar, por el uso de "gets" (desaconsejado en las versiones recientes de C, porque los datos grandes pueden desbordar sin que te des cuenta ni nada te avise) y por no incluir un "return" al final.

Pero aparte de eso, funciona como era de esperar (dentro de que sólo hay un artista y un tamaño pero muchas canciones distintas): cada vez que añades, los datos se guardan correctamente, se muestra correctamente y buscan correctamente, al menos con el compilador GCC de Linux relativamente actualizado.

Si te está fallando, puede ser que estés introduciendo datos demasiado grandes, que estén sobreescribiendo la posición de memoria en la que está tu contador (ése es el gran problema de "gets") o que uses un compilador antiguo que tenga algún fallo, porque la lógica, salvando el riesgo de desbordamientos, es razonable.






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)