Ayuda programa en C que lee una cadena

Iniciado por Herdo, 5 Marzo 2016, 15:11 PM

0 Miembros y 1 Visitante están viendo este tema.

Herdo

Hola, soy nuevo programando en C y por el momento me esta gustando. En la universidad me mandaron a hacer un ejercicio que es sobre un programa que lee una cadena introducida por el usuario.
Luego de leer la cadena el programa mostrará por pantalla un mensaje de error en caso de que algo este mal introducido o un mensaje correcto.
El problema que tengo es que no entiendo muy bien como hacer que lea la cadena. Pongo un ejemplo del código que tengo hecho y unas imágenes de como debería funcionar el programa.

#include<stdio.h>

typedef struct {
char nombre [30];
int num_ejemplares;
char sección;
int habitaculo;
int dia;
int mes;
int año;
} Especie;

int menu (void) {
printf ("Prototipo de la Reserva natural.\n");
printf ("1. Introducir una nueva especie.\n");
printf ("2. Listar las especies alojadas.\n");
printf ("3. Mostrar estadisticas.\n");
printf ("4. Salir.\n");
}

int main () {
int op;
while (op != 4){
op == menu ();
scanf ("%d", &op);
if (op == 1) {
nuevo ();
}
}
}
//Opcion 1 que permite introducir una nueva especie
void nuevo () {
Especie e;
int i;
char especie [100];
gets (especie);
int cont;
//Mientras sea diferente del - leera el texto
while (especie [i] != '-') {
especie [i] = e.nombre;
}
//Se le suma 1 a la posicion de i ya que terminaria en - y debe comenzar a leer desde lo siguiente
i = i + 1;
while (especie [i] != '-') {
especie [i] = e.num_ejemplares;
//Controlara que el numero de ejemplares sea un numero y no un caracter
if (e.num_ejemplares <= '0' || e.num_ejemplares >= '100') {
printf ("--> Error en el formato de datos.");
}
}
i = i + 1;
//Lee el dia que introducido
while (especie [i] != '/') {
especie [i] = e.dia;
//Controla que el formato del dia este bien introducido
if (e.dia <= 0 || e.dia > 31) {
printf ("--> Error en el formato de datos.");
}
}
i = i + 1;
//Lee el mes introducido
while (especie [i] != '/') {
especie [i] = e.mes;
//Controla que el formato del mes este bien introducido
if (e.mes <= 0 || e.dia > 12) {
printf ("--> Error en el formato de datos.");
}
}
i = i + 1;
//Lee el año introducido
while (especie [i] != '/') {
especie [i] = e.dia;
//Controla que el formato del año este bien introducido
if (e.dia <= 1970 || e.dia >= 2060) {
printf ("--> Error en el formato de datos.");
}
}
i = i + 1;
//Lee en que sección esta introducido
while (especie [i] != '-') {
especie [i] = e.sección;
//Controla que la sección este introducida con mayusculas
if (e.sección < 'A' || e.sección > 'Z') {
printf ("--> Error en el formato de datos.");
}
}
i = i + 1;
//Al estar en el final tiene que encontrarse con el \0 para saber que es el habitaculo
while (especie [i] != '\0') {
especie [i] = e.habitaculo;
//Controlara que el numero de habitaculo sea un numero y no un caracter
if (e.habitaculo <= '0' || e.habitaculo >= '100') {
printf ("--> Error en el formato de datos.");
}
}
printf ("---> Especie introducida con exito.\n");
}


Así es como debería funcionar el programa.


Y así debería dar error.


Otra cosa que no se muy bien como hacerla es sobre los espacios libres, se que tiene que ser con un array de 10 casillas que guarde los datos introducidos.

Perdón si es un desastre el código, pero soy nuevo en esto de la programación.

Gracias.

MAFUS

Las imágenes no se ven.

Sobre tu código:

#include<stdio.h>

typedef struct {
    char nombre [30];
    int num_ejemplares;
    char sección; // En muchos compiladores va a fallar tu nombre de variable
                  // pues solo esperan letras del abecedario inglés: sin acentos.
    int habitaculo;
    int dia;
    int mes;
    int año; // Reafirmo lo dicho antes: en este caso se van a quejar de la letra ñ.
} Especie;

int menu (void) {
    printf ("Prototipo de la Reserva natural.\n");
    printf ("1. Introducir una nueva especie.\n");
    printf ("2. Listar las especies alojadas.\n");
    printf ("3. Mostrar estadisticas.\n");
    printf ("4. Salir.\n");
   
    // Aquí deberías pedir la opción numérica y devolverla
    // con el return de la función.
}

int main () {
    int op;
    while (op != 4){ // Varias cosas: op NO está inicializado, no
                     // debes usar un valor que no hayas inicializado antes.
                     // Los menús mejor hacerlos con un do ... while pues
                     // seguro que querrás mostrarlo almenos una vez.
        op == menu (); // Esto funcionaría en caso de que la función
                       // menu() regresara algo controlado.
        scanf ("%d", &op); // Esta linea y la anterior son contradictorias:
                           // ¿Es la función menu() la que te devuelve la opción
                           // o lo adquieres ahora en la función main()?
        if (op == 1) { // Para resolver opciones de menú queda más límpio el
                       // uso de la sentencia switch
            nuevo ();
        }
    }
}
    //Opcion 1 que permite introducir una nueva especie
void nuevo () {
    Especie e; // e es una variable local. Cuándo termine la función nuevo()
               // e va a desaparecer y con ella todo el trabajo que hayas
               // hecho para rellenarla. C permite devolver estructuras así
               // que en vez de declarar void nuevo() deberías haber declarado
               // Especie nuevo() y recogerlo en main mediante algo parecido a
               // Especie e = nuevo();
    int i;
    char especie [100];
    gets (especie); // gets no se debería usar porqué al no controlar la cantidad
                    // de datos que entran en la cadena podría sobrepasarse el tamaño
                    // máximo del buffer y se sobreescribirían otros datos del programa.
                    // usar fgets(stdin, especie, 100); en su lugar.
    int cont;
    //Mientras sea diferente del - leera el texto
    while (especie [i] != '-') { // Varias cosas aquí que sirven para el resto de
                                 // estructuras similares que hay en el programa:
                                 // i no está inicializado y no se sabe que valor tiene.
                                 // Estás leyendo quien sabe donde.
                                 // Por otra parte i no se actualiza por tanto siempre
                                 // trabajarás sobre la misma posición de memoria.
                                 // Otra cosa: cuándo has recibido una línea formateada con
                                 // delimitadores puedes usar la función strtok de string.h
                                 // para recoger los diferentes datos de la cadena.
        especie [i] = e.nombre; 
    }
    //Se le suma 1 a la posicion de i ya que terminaria en - y debe comenzar a leer desde lo siguiente
    i = i + 1; // Para incrementar en 1 una variable numérica es mejor usar el operador unario ++
               // Aquí quedaría mejor i++;
               // O mejor aún, sobre todo en compiladores antiguos usar ++i por la razón de que el
               // código objeto quedaba aún más optimizado.
    while (especie [i] != '-') {
        especie [i] = e.num_ejemplares; // Las cadenas no se copian mediante el operador =
                                        // esto te serviría para copiar punteros pero en este caso
                                        // perderías la información cuándo el usuario hiciera una nueva
                                        // entrada. En su lugar deberías usar strncpy de string.h
                                        // Por otra parte, y dejando de lado el punto anterior, aquí
                                        // tienes un error de lógica y es que intentas guardar en la cadena
                                        // desde la que estas, en teoría, leyendo, el el valor de la variable
                                        // que debería ser el destino. ***Aunque está mal*** debería ser
                                        // e.num_ejemplares = especie[i]
                                        // Por cierto, i sigue sin saberse a donde se apunta e itera siempre
                                        // en la misma posición. A partir de ahora obviaré este error.
                                        // e.num_ejemplares es un entero, para un usuario es imposible que
                                        // te escriba un entero como tipo de dato en una cadena.
                                        // Deberías crear una cadena auxiliar con, y solo con, el dato numérico
                                        // y pasarlo a entero mediante la siguiente construcción:
                                        // sscanf(cad_auxiliar, "%i", e.num_ejemplares);
        //Controlara que el numero de ejemplares sea un numero y no un caracter
        if (e.num_ejemplares <= '0' || e.num_ejemplares >= '100') { // Entre comillas simples solo se ponen
                                                                    // constantes de caracter.
                                                                    // Las constantes de cadena se ponen entre
                                                                    // comillas dobles.
                                                                    // Pero en tu caso lo que estás comparando son
                                                                    // constantes numéricas por lo que deben ir sin
                                                                    // delimitar.
            printf ("--> Error en el formato de datos.");
        }
    }
    i = i + 1;
    //Lee el dia que introducido
    while (especie [i] != '/') {
        especie [i] = e.dia;
        //Controla que el formato del dia este bien introducido
        if (e.dia <= 0 || e.dia > 31) {
            printf ("--> Error en el formato de datos.");
        }
    }
    i = i + 1;
    //Lee el mes introducido
    while (especie [i] != '/') {
        especie [i] = e.mes;
        //Controla que el formato del mes este bien introducido
        if (e.mes <= 0 || e.dia > 12) {
            printf ("--> Error en el formato de datos.");
        }
    }
    i = i + 1;
    //Lee el año introducido
    while (especie [i] != '/') {
        especie [i] = e.dia;
        //Controla que el formato del año este bien introducido
        if (e.dia <= 1970 || e.dia >= 2060) { // Supongo que aquí querías decir e.año
            printf ("--> Error en el formato de datos.");
        }
    }
    i = i + 1;
    //Lee en que sección esta introducido
    while (especie [i] != '-') {
        especie [i] = e.sección;
        //Controla que la sección este introducida con mayusculas
        if (e.sección < 'A' || e.sección > 'Z') {
            printf ("--> Error en el formato de datos.");
        }
    }
    i = i + 1;
    //Al estar en el final tiene que encontrarse con el \0 para saber que es el habitaculo
    while (especie [i] != '\0') {
        especie [i] = e.habitaculo;
        //Controlara que el numero de habitaculo sea un numero y no un caracter
        if (e.habitaculo <= '0' || e.habitaculo >= '100') {
            printf ("--> Error en el formato de datos.");
        }
    }
    printf ("---> Especie introducida con exito.\n");
    // La función main debe devolver un entero. El estándar dice que se debe
    // devolver 0 si el programa ha tenido éxito. C define una macro llamada
    // EXIT_SUCCESS en stdlib.h usada para éste menester. Puedes elegir la forma
    // que quieras.
}