Problema con una funcion

Iniciado por ThronerAXE, 8 Mayo 2013, 18:16 PM

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

ThronerAXE

Buenas tengo este problema, estoy creando un pedazo de funcion(le tengo que agregar mas funciones) y estoy usando la estructura switch, mi problema es que cuando el programa corre, no entra en la funcion, aqui esta el codigo:

//Ultimo Programa de funciones
#include <stdio.h>
#include <conio.h>
//Prototipos
int menu(void);
int semana(char);
//Programa Principal
void main()
{ int opcion;
  char dia;
  float valor;

  while((opcion=menu())!=2)
  { switch(opcion)
    { case 1: clrscr();
              printf("\nIngrese la inicial del dia: ");
              scanf("%c",&dia);
              printf("\nEl dia de la semana que le corresponde es el %d",semana(dia));
              break;
    }
  }
}
//Funciones
int menu(void)
{ int opc;
  clrscr();
  printf("\t\t\tMENU");
  printf("\n1...Para los dias de la semana");
  printf("\n2...SALIR");
  do
  { printf("\n\nIngrese su opcion y presione enter: ");
    scanf("%d",&opc);
    if(opc<1 || opc>2)
    { printf("\nHa ingresado un valor incorrecto!!!");
      getch();
    }
  }while(opc<1 || opc>2);
  return opc;
}

int semana(char fdia)
{ int fndia;
  switch(fdia)
  { case 'd': fndia=1;
              break;
    case 'l': fndia=2;
              break;
    case 'm': fndia=3;
              break;
    case 'M': fndia=4;
              break;
    case 'j': fndia=5;
              break;
    case 'v': fndia=6;
              break;
    case 's': fndia=7;
              break;
  }
return fndia;
}

leosansan

#1
Problema con el buffer, que en este caso se soluciona dejando un espacio en blanco en los scanf. Esto me da como salida:

Código (cpp) [Seleccionar]

                       MENU
1...Para los dias de la semana
2...SALIR

Ingrese su opcion y presione enter: 1

Ingrese la inicial del dia: s

El dia de la semana que le corresponde es el 7                  MENU
1...Para los dias de la semana
2...SALIR

Ingrese su opcion y presione enter: 1

Ingrese la inicial del dia: d

El dia de la semana que le corresponde es el 1                  MENU
1...Para los dias de la semana
2...SALIR


Y el código con los espacios puestos:

Código (cpp) [Seleccionar]
//Ultimo Programa de funciones
#include <stdio.h>
#include <conio.h>
//Prototipos
int menu(void);
int semana(char);
//Programa Principal
int main()
{ int opcion;
 char dia;
 float valor;

 while((opcion=menu())!=2)
 { switch(opcion)
   { case 1: clrscr();
             printf("\nIngrese la inicial del dia: ");
             scanf(" %c",&dia);
             printf("\nEl dia de la semana que le corresponde es el %d",semana(dia));
             break;
   }
 return 0;
}
}
//Funciones
int menu(void)
{ int opc;
 clrscr();
 printf("\t\t\tMENU");
 printf("\n1...Para los dias de la semana");
 printf("\n2...SALIR");
 do
 { printf("\n\nIngrese su opcion y presione enter: ");
   scanf(" %d",&opc);
   if(opc<1 || opc>2)
   { printf("\nHa ingresado un valor incorrecto!!!");
     getch();
   }
 }while(opc<1 || opc>2);
 return opc;
}


int semana(char fdia)
{ int fndia;
 switch(fdia)
 { case 'd': fndia=1;
             break;
   case 'l': fndia=2;
             break;
   case 'm': fndia=3;
             break;
   case 'M': fndia=4;
             break;
   case 'j': fndia=5;
             break;
   case 'v': fndia=6;
             break;
   case 's': fndia=7;
             break;
 }
return fndia;
}



Saluditos!. ....  


pacoperico

Has de vaciar el buffer del stdin despues de usar scanf() en la definicion de tu funcion int menu(void). La forma mas sencilla es añadiendo esta linea justo despues del scanf():

Código (cpp) [Seleccionar]
while(getchar()!='\n');

Otras cosa ese switch con un solo case lo puedes quitar del codigo asi como la variable float valor que no la usas para nada. Yo la funcion main() siempre la declaro como int main() y con su return 0, en ver de void main() es costumbre mia. Y la libreria de conio.h siempre intento no usarla tiene funciones que a veces pueden ser problematicas.

Código (c++) [Seleccionar]
#include <stdio.h>
#include <stdlib.h>

//Prototipos
int menu(void);
int semana(char);
//Programa Principal


int main()
{ int opcion;
 char dia;
 
 while((opcion=menu())!=2)
   {
system("cls");
           printf("\nIngrese la inicial del dia: ");
           scanf("%c",&dia);
           printf("\nEl dia de la semana que le corresponde es el %d\n",semana(dia));
system("pause");          
}
 return 0;
}


//Funciones
int menu(void)
{ int opc;
 system("cls");
 printf("\t\t\tMENU");
 printf("\n1...Para los dias de la semana");
 printf("\n2...SALIR");
 do
 { printf("\n\nIngrese su opcion y presione enter: ");
   scanf("%d",&opc);
while(getchar()!='\n'); //limpieza del buffer del stdin
   if(opc<1 || opc>2)
   { printf("\nHa ingresado un valor incorrecto!!!");
     getchar();
   }
 }while(opc<1 || opc>2);
 return opc;
}

int semana(char fdia)
{ int fndia = 0;
 switch(fdia)
 { case 'd': fndia=1;
             break;
   case 'l': fndia=2;
             break;
   case 'm': fndia=3;
             break;
   case 'M': fndia=4;
             break;
   case 'j': fndia=5;
             break;
   case 'v': fndia=6;
             break;
   case 's': fndia=7;
             break;
 }
return fndia;
}

leosansan

#3
Cita de: pacoperico en  8 Mayo 2013, 19:05 PM
Has de vaciar el buffer del stdin despues de usar scanf() en la definicion de tu funcion int menu(void). La forma mas sencilla es añadiendo esta linea justo despues del scanf():

Código (cpp) [Seleccionar]
while(getchar()!='\n');

...............

Como comenté en el post anterior, en este caso concreto en que sólo se pueda quedar en el buffer es el \n, dejar el espacio en blanco antes del scanf me parece la opción más eficiente y breve. Otra cosa es que quedara resto de una cadena o algo así.

Por lo demás muy de acuerdo en el no uso  de la librería conio y , como digo yo, sus acólitos getch y compañía.

Un fuerte Saludo pacoperico.


P.D: Otra cosa a mejorar es el de opción, ya que si le entran una letra en lugar de un 1 o 2 se quedará en el sitio.

pacoperico

jaja no sabia yo eso de poner un espacio en blanco dentro del scanf() para limpiar el \n en el buffer del stdin. Lo he probado y funciona, es mucho mas sencillo que añadir:
Código (cpp) [Seleccionar]
while(getchar()!='\n');

Al codigo pero bueno, yo nunca dejare de usarlo xD.

amchacon

Cita de: leosansan en  8 Mayo 2013, 19:38 PMPor lo demás muy de acuerdo en el dichoso uso de la librería conio y , como digo yo, sus acólitos getch y compañía.
Creo que querías decir "desacuerdo"

Puedes sustituir getch por getchar(), asi no tendrás que usar la librería conio (solo funciona en Windows, es una buena costumbre hacer las cosas multiplataforma).
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

leosansan

Cita de: amchacon en  8 Mayo 2013, 21:08 PM
Creo que querías decir "desacuerdo"

Puedes sustituir getch por getchar(), asi no tendrás que usar la librería conio (solo funciona en Windows, es una buena costumbre hacer las cosas multiplataforma).

Desacuerdo total, gracias por la precisión, reeditaré el post para que no queden dudas.

Saluditos!. ....

ThronerAXE

Muchas gracias por sus consejos, muchos me dicen sobre no usar la librería conio.h pero el problema esque asi lo evalua la profesora en la universidad. Otra cosita es sobre la limpieza del buffer utilizando el codigo...
    while(getchar()!='\n');
La profesora nos ha dicho sobre este codigo que limpia el buffer tambien...
fflush(stdin);
mi pregunta, ¿Hacen la misma funcion?¿y que diferencia hay en colocar un fflush(stdin) y un fflush(stdout). Yo pues la verdad, me gusta experimentar metiendo codigos y ver como interactuan, pero la verdad esque no veo que me altere ni me modifique el programa si las utilizo o no...

Otra cosita, les habia comentado que el codigo que habia posteado era un pedazo de funcion, ahora le fui a agregar otra funcion(y es por eso que habia agregado el switch), bueno pues resulta que  es el calculo de una funcion matematica, al cual le tengo que pedir que ingrese un valor numerico que sea menor a 1 y diferente de -1/2 y que ademas tengo que validar. el programa corre normal, pero cuando le ingreso el valor se queda en el ciclo y no sale nunca, solamente funciona cuando le doy al valor de la variable el numero 0, alli si funciona, aqui esta el codigo...//Cuarto Programa de funciones
#include <stdio.h>
#include <conio.h>
#include <math.h>
//Prototipos
int menu(void);
int semana(char);
float fun_x(float);
//Programa Principal
void main()
{ int opcion;
  char dia;
  float valor;

  while((opcion=menu())!=3)
  { switch(opcion)
    { case 1: clrscr();
              printf("\n\nDebe ingresar las letras en minuscula, a excepcion del dia miercoles en\n donde debes ingrasarla en mayuscula");
              printf("\nIngrese la primera letra del dia de la semana: ");
              scanf(" %c",&dia);
              printf("\nEl dia de la semana que le corresponde es el %d",semana(dia));
              getch();
              break;
      case 2: clrscr();
              do
              { printf("\nIngrese el valor de X: ");
                scanf("%f",&valor);
                if(valor!=(-1/2) || valor>1)
                { printf("debe ingresar un valor menor a 1 y diferente de -1/2");
                  getch();
                }
              }while(valor!=(-1/2) || valor>1);
              printf("\n\nEl valor de la funcion es de %.2f",fun_x(valor));
              getch();
              break;
    }
  }
}
//Funciones
int menu(void)
{ int opc;
  clrscr();
  printf("\t\t\tMENU");
  printf("\n1...Para los dias de la semana");
  printf("\n2...Para calcular el valor de una funcion");
  printf("\n3...SALIR");
  do
  { printf("\n\nIngrese su opcion y presione enter: ");
    scanf("%d",&opc);
    if(opc<1 || opc>3)
    { printf("\nHa ingresado un valor incorrecto!!!");
      getch();
    }
  }while(opc<1 || opc>3);
  return opc;
}

int semana(char fdia)
{ int fndia;
  switch(fdia)
  { case 'd': fndia=1;
              break;
    case 'l': fndia=2;
              break;
    case 'm': fndia=3;
              break;
    case 'M': fndia=4;
              break;
    case 'j': fndia=5;
              break;
    case 'v': fndia=6;
              break;
    case 's': fndia=7;
              break;
  }
return fndia;
}

float fun_x(float fx)
{ float fresul;

  fresul=pow(fx,(2*fx+1))-5*pow(M_E,(3*log10(fabs(sqrt(1-fx)))));
  return fresul;
}


PD: esta bien que en los codigos utilize quebrados(fracciones), o debería utilizar decimales, lo digo en el caso de la segunda funcion en donde debo validar el valor ingresado por el usuario

pacoperico

Cita de: ThronerAXE en  9 Mayo 2013, 01:22 AMmi pregunta, ¿Hacen la misma funcion?¿y que diferencia hay en colocar un fflush(stdin) y un fflush(stdout). Yo pues la verdad, me gusta experimentar metiendo codigos y ver como interactuan, pero la verdad esque no veo que me altere ni me modifique el programa si las utilizo o no...

Podemos pensar a priori que fflush(stdin) limpia el buffer de entrada del stdin (teclado) ya que por su parte fflush(stdout) limpia el buffer de salida enviandolo al stdout (pantalla), pero no es asi ya que fflush(stdin) no esta definido en el estandar y su comportamiento es algo totalmente imprevisible. En la chincheta de este foro lo explican mas detalladamente:
http://foro.elhacker.net/programacion_cc/lo_que_no_hay_que_hacer_en_cc_nivel_basico-t277729.0.html

Cita de: ThronerAXE en  9 Mayo 2013, 01:22 AMPD: esta bien que en los codigos utilize quebrados(fracciones), o debería utilizar decimales, lo digo en el caso de la segunda funcion en donde debo validar el valor ingresado por el usuario

Ese -1/2 que tienes en tu codigo, el lenguaje C lo interpreta como una division entre dos numeros enteros (tipo int) y su resultado debera ser un numero entero (de tipo int). Si el resultado de la operacion matematica contiene decimales C lo redondea para convertirlo en un numero entero. En este caso el lenguaje C  transforma tu -1/2 a 0. Esto lo puedes comprobar facilmente:
Código (cpp) [Seleccionar]
  if(0 == (-1/2))
  printf("cierto");
  else
  printf("falso");


Lo mas sencillo seria que cambiases el -1/2 por su valor de -0.5. Otra opcion que tambien tienes, seria sustituir esa division entre numeros enteros (tipo int) por una division entre numeros decimales (tipo float), solo has de añadirle una parte decimal es decir, en lugar de escribir -1/2 escribes -1.0/2.0. Para nosotros los humanos -1/2 es lo mismo que -1.0/2.0 pero para el lenguaje C no lo es.



amchacon

fflus(stdin) solo funciona en Windows. Si quieres que tu código sea multiplataforma debes usar otras alternativas.

Francamente, me parece vergonsozo que profesores recomienden cosas como esa. El toque de gracia será que también haya recomendado el Devcpp (o peor aún, turbo C xD).

Personalmente, no uses la librería conio. La única función que estás utilizando es getch() y puedes usar getchar() en su lugar (es correcto, la profesora no te va a decir que no). Si te da a elegir, usa el otro método para limpiar el buffer. No solo hay que aprobar sino acostumbrarse a programar bien.
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar