Que puede estar fallando? (C)

Iniciado por Saberuneko, 9 Marzo 2011, 17:24 PM

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

Saberuneko

Llevo pegándome con este varias horas, pero no consigo que funcione.

Enunciado: Se desea elaborar una encuesta con objeto de hacer un estudio sobre el consumo de tabaco. Para ello se solicita un programa que deberá permitir la recogida de datos sobre una muestra de 1000 personas fumadoras. La recogida de datos se realizará sobre un vector (DATOS) de 1000 elementos. Cada elemento recogerá la siguiente información:

Codigo
Cigarrillos Diarios
Marca

El programa deberá permitir:
1.- Recogida de datos
2.- Media de cigarrillos fumados por persona y dia
3.- Visualización del consumo por marcas
4.- Marca con mayor índice de fumadores
5.- Fin

Opcion 1: Se llamara a un procedimiento que permitirá la carga del vector (esta opción no terminará hasta que se completen los datos de todo el vector.

Opcion 2: Se llamará a una función que retornará dicha media

Opcion 3: Para la realización de esta opción se dispondrá de un vector de estructuras que contendrá la siguiente información:

Marca
Numero cigarrillos

Este vector se supone ya cargado con el campo Marca. El campo numero_cigarrillos está a cero, se completará por programa en esta opción. Para ello una vez que se hayan recogido los datos de la encuesta se recorrerá el vector datos enviando "cada registro" a un procedimiento que buscará la casilla correspondiente en el vector marcas para incrementar el campo Numero cigarrillos (se supone que estan incluidas todas las marcas)

Con el vector marcas ya actualizado se procederá a la visualización

Opción 4: Función que retornará dicha estructura para su posterior visualización.

Esto es lo que tengo hecho, pero no funciona.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N 5 /*Tras pruebas, 1000*/
#define M 5 /*Cantidad de marcas, no definida en enunciado, 5 por poner varias*/
#define L 20 /*Longitud de cadena*/

typedef struct
{
   int cod;
   int cig;
   char marca;
} encuesta;

typedef struct
{
   char marca2[L];
   int numero_cig;
} vector;

void menu();
void intro(encuesta* dat);
float media(encuesta* dat);
void cons_marca(encuesta* dat, vector* mar);
void mejor_marca(vector* mar);
int posicionar(char data[], char mar[]);

/*Modulo Principal*/

void main()
{
   encuesta datos[N];
   vector marcas[M]= /*Viene pre-cargado segun el enunciado*/
   {{"Malboro",0},
   {"Lucky",0},
   {"Strike",0},
   {"Camel",0},
   {"Otra",0}};

   int op;
   float mid;

   system("cls");
   menu();
   scanf("%d",&op);
   while(op!=5)
   {
    switch(op)
      {
         case 1:
          intro(datos);
            break;
         case 2:
          mid=media(datos);
            printf("\nMedia: %f",mid);
            break;
         case 3:
          cons_marca(datos,marcas);
            break;
         case 4:
          mejor_marca(marcas);
            break;
         case 5:
          printf("\nSaliendo de la aplicacion...");
            getchar();
         default:
          printf("\nOpcion erronea");
      }

      system("cls");
      menu();
      scanf("%d",&op);
   }
}

/*0.- Menu*/
void menu()
{
   system("cls");
   printf("\nMENU:\n--\n");
   printf("1.- Recogida de datos\n");
   printf("2.- Media de Cigarrillos\n");
   printf("3.- Consumo por Marcas\n");
   printf("4.- Marca con Mayor Consumo\n");
   printf("5.- Fin\n");
   printf("Seleccione una opcion... ");
}

/*1.- Recogida de datos*/
void intro(encuesta* dat)
{
   int cont;

   system("cls");
   for(cont=0;cont<N;cont++)
   {
      dat[cont].cod=cont; /*Cod Numerico automatico segun introduccion*/
      printf("Cigarrillos Diarios: ");
      scanf("%d",&dat[cont].cig);
      printf("\nMarca: ");
      scanf("%s",dat[cont].marca);
   }
}

/*2.- Media de cigarrillos fumados por persona y dia*/
float media(encuesta* dat)
{
   int cont;
   float mid=0;

   system("cls");
   for(cont=0;cont<N;cont++)
   {
    mid=mid+dat[cont].cig;
   }
   mid=mid/N;
   return mid;
}

/*3.- Visualizacion del consumo por marcas*/
void cons_marca(encuesta* dat, vector* mar)
{
   int cont,pos;
   for(cont=0;cont<N;cont++)
   {
    pos=posicionar(&dat[cont].marca,mar);
    mar[pos].numero_cig=mar[pos].numero_cig+dat[cont].cig;
   }
   system("cls");
   printf("Consumo por marcas:\n--\n");
   for(cont=0;cont<N;cont++)
   {
    printf("%s: %d\n",dat[cont].marca,mar[pos].numero_cig);
   }
}

/*4.- Marca con mayor indice de fumadores*/
void mejor_marca(vector* mar)
{
   int cont,max=0,pos;
   for(cont=0;cont<N;cont++)
   system("cls");
   {
    if(mar[cont].numero_cig>max)
      {
      max=mar[cont].numero_cig;
        pos=cont;
      }
   }
   printf("Mejor Marca: %s", mar[pos].marca2);
}

/*3.1- Localizacion de la posicion correcta para incrementar el valor de dat[].cig*/
int posicionar(char data[], char mar[])
{
   int cont=0,pos,found=0;
   while((cont<M)||(!found))
   {
    if(strcmp(data,mar)==0);
      {
      pos=cont;
        found=1;
      }
      cont++;
   }
   return pos;
}


A ver si me podéis echar una mano... todavía programo bastante mal y me queda mucho por aprender...

Un saludo y gracias por adelantado.

Akai

#1
Mira los avisos del compilador:

algo.c: En la función 'intro':
algo.c:102:7: aviso: el formato '%s' espera el tipo 'char *', pero el argumento 2 es de tipo 'int'
algo.c: En la función 'cons_marca':
algo.c:127:5: aviso: se pasa el argumento 2 de 'posicionar' desde un tipo de puntero incompatible
algo.c:27:5: nota: se esperaba 'char *' pero el argumento es de tipo 'struct vector *'
algo.c:134:5: aviso: el formato '%s' espera el tipo 'char *', pero el argumento 2 es de tipo 'int'


Las llamadas a system son algo tirando a mala costumbre, tu código por ejemplo no compila se puede usar en linux debido a que cls no es un comando de sistema de linux.

No te vendría mal compilar con avisos (en gcc o mingw -Wall -pedantic)

Por otro lado, no se exactamente si es lo que pretendes, pero
char marca

Con eso guardas sólo un caracter, si quieres guardar una cadena, creo que ya sabes qué toca

Saberuneko

Cita de: Akai en  9 Marzo 2011, 18:12 PM
Mira los avisos del compilador:

algo.c: En la función 'intro':
algo.c:102:7: aviso: el formato '%s' espera el tipo 'char *', pero el argumento 2 es de tipo 'int'
algo.c: En la función 'cons_marca':
algo.c:127:5: aviso: se pasa el argumento 2 de 'posicionar' desde un tipo de puntero incompatible
algo.c:27:5: nota: se esperaba 'char *' pero el argumento es de tipo 'struct vector *'
algo.c:134:5: aviso: el formato '%s' espera el tipo 'char *', pero el argumento 2 es de tipo 'int'

No te vendría mal compilar con avisos (en gcc o mingw -Wall -pedantic)

En clase estoy forzado a usar el Borland, una versión del año de la pera... La mitad de los avisos son erróneos o están referidos a líneas equivocadas. A ver si con estos lo acabo arreglando.

CitarLas llamadas a system son algo tirando a mala costumbre, tu código por ejemplo no compila se puede usar en linux debido a que cls no es un comando de sistema de linux.

Bueno, nuestra profesora nos orienta hacia windows, es por eso que lo hice así. Sé que system da problemas de portabilidad, gracias por el aviso de todos modos. ^^ (Hay un equivalente para limpiar pantalla?)

CitarPor otro lado, no se exactamente si es lo que pretendes, pero
char marca

Con eso guardas sólo un caracter, si quieres guardar una cadena, creo que ya sabes qué toca

Whops! Ahora lo veo... vaya fallo mas gordo.

Muchas Gracias por la ayuda, le echo un vistazo mañana a ver si consigo que funcione. ^^

Akai

el equivalente para limpiar la pantalla portable, si no me equivoco, es fflush(stdout)  Otra opción puede ser imprimir de golpe unos 20 o 30 saltos de linea xD. Quizá alguien quiera añadir algo sobre el tema.

El problema con system es que haces una llamada concreta al sistema, entonces, pongamos que "cls" existiese en ambos sistemas, no seria un problema, pero el equivalente de cls en el estándar POSIX es clear, por tanto, ya no puedes hacer una llamada cls en un SO que utilice el estándar POSIX.

Sobre lo del borland... en clase usa lo que tengas, en casa, prueba otros compiladores xD

Saberuneko

El fflush es un comando prohibido en mi clase, considerado como una de las peores costumbres. O_o
(La profesora ni siquiera nos había dicho su utilidad)
Ahora no sé qué hacer para limpiar la pantalla... :-\ :-\

En casa, iba a probar con eclipse, pero no me funciona. Así que tiré también de Borland. :-( :-(

Akai

#5
Cita de: Saberuneko en 10 Marzo 2011, 09:35 AM
El fflush es un comando prohibido en mi clase, considerado como una de las peores costumbres. O_o
(La profesora ni siquiera nos había dicho su utilidad)
Ahora no sé qué hacer para limpiar la pantalla... :-\ :-\

fflush ES una mala costumbre sobre streams de ENTRADA vease STDIN ya que tiene un comportamiento indeterminado (puede ir bien, puede fallar, puede explotar), sobre STDOUT, o streams/ficheros de salida NO tiene problema.

EDIT: Para limpiar la pantalla, sigue usando system("cls") en tu entorno de clase, simplemente te quise hacer notar los problemas que puede dar cuando portes tu código a otros sitios.

EDIT2: empiezo a tener dudas de que fflush limpie la pantalla. (Consultando referencia) En efecto, lo que hace es volcar cualquier dato en el buffer al fichero, así que si te quedase algo en el buffer, precisamente no te va a limpiar la pantalla.

"Solución":
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");

Eso en principio, "limpia" la pantalla. Al fin y al cabo, cuando en Linux haces un "clear" parece ser que hace esto. o al menos si subes con el scroll hacia arriba en el shell, se muestra lo que supuestamente acabas de limpiar

4rkn63l

A ver...

Si usas funciones propias del sistema, te quedas sin portabilidad.  :-\

Si usas fflush(stdout) propio del lenguaje aun siendo estandar, la profe te pone cero y te manda a imprimir 1000000 veces en pantalla "No usare fflush(stdout)".  :xD

La verdad no se por que hoy en dia siguen haciendo uso de ese tipo de compiladores tipo Borland o turbo C, usando gotoxy(), conio.h y compañia limitada.

En mi opinion en linux la mejor opcion es Geany+gcc y para windows Dev-C++.

Akai

Cita de: 4rkn63l en 10 Marzo 2011, 10:10 AM

Si usas fflush(stdout) propio del lenguaje aun siendo estandar, la profe te pone cero y te manda a imprimir 1000000 veces en pantalla "No usare fflush(stdout)".  :xD

Cual es el problema con fflush y un stream de salida?