basura en mi programa

Iniciado por m@o_614, 6 Diciembre 2013, 00:47 AM

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

m@o_614

Saludos estoy haciendo un programa que contiene un menu para elegir diferentes operaciones aritmeticas, ya se que no se puede usar fflush(stdin) para limpiar el buffer, pero ya le puse el fgets + sscanf en las partes donde crei que me daba problemas pero aun asi sigue con basura, tengo que cambiar cada uno de los scanf() que tengo en mi codigo por un fgets + sscanf???? lo que pasa es que son muchisimos y crei que con solo ponerle 2 seria mas que suficiente

#include <stdio.h>
#include <stdlib.h>
#define TAM 5
#define ARITMETICA_SIMPLE 1
#define ARITMETICA_BINARIA 2
#define FACTORIAL 3
#define TABLA_MULTIPLICAR 4
#define SALIR 5
int main()
{
    //Variables de uso interno del programa
    int continuar = 1,i,factorial = 1;
    //Variables para entrada de datos
    int opcion,numero1,numero2,numero_factorial,multiplicando,multiplicador;
    char operador,buffer[TAM];
    do
    {
        //Menu principal
        printf("CALCULADORA v1.0\n\n");
        printf("Elige una de las siguientes opciones:\n");
        printf("1. Aritmetica simple con suma de enteros a+b\n");
        printf("2. Aritmetica extendida binaria\n");
        printf("3. Factorial de n (n!)\n");
        printf("4. Detallar una tabla de multiplicar\n");
        printf("5. Salir\n");
        printf("Opcion a elegir? ");
        fgets(buffer,sizeof(buffer),stdin);
        sscanf(buffer,"%d",&opcion);
        switch(opcion)
        {
            //Aritmetica simple con suma de enteros a+b
            case ARITMETICA_SIMPLE:
               printf("Dame el valor de a = ");
               scanf("%d",&numero1);
               printf("Dame el valor de b = ");
               scanf("%d",&numero2);
               printf("%d + %d = %d",numero1,numero2,numero1+numero2);
               break;
            //Aritmetica extendida binaria (+,-,*,/,%modulo)
            case ARITMETICA_BINARIA:
               printf("Escribe el operador (+,-,*,/,%%): ");
               fgets(buffer,sizeof(buffer),stdin);
               sscanf(buffer,"%c",&operador);
               printf("\nDame el valor de a = ");
               scanf("%d",&numero1);
               printf("Dame el valor de b = ");
               scanf("%d",&numero2);
               switch(operador)
               {
                   case '+':
                      printf("%d %c %d = %d\n",numero1,operador,numero2,numero1+numero2);
                      break;
                   case '-':
                      printf("%d %c %d = %d\n",numero1,operador,numero2,numero1-numero2);
                      break;
                   case '*':
                      printf("%d %c %d = %d\n",numero1,operador,numero2,numero1*numero2);
                      break;
                   case '/':
                      printf("%d %c %d = %d\n",numero1,operador,numero2,numero1/numero2);
                      break;
                   case '%':
                      printf("%d %c %d = %d\n",numero1,operador,numero2,numero1%numero2);
                      break;
                   default:
                      printf("No hay un resultado calculable\n");
                      printf("%d %c %d = 0\n",numero1,operador,numero2);
               }
               break;
            //Factorial de n (n!)
            case FACTORIAL:
               printf("Dame el valor de n = ");
               scanf("%d",&numero_factorial);
               if(numero_factorial < 0)
                  printf("El factorial de %d no esta definido\n",numero_factorial);
               else if(numero_factorial == 0)
                  printf("El factorial de 0 es 1\n");
               else
               {
                   for(i = numero_factorial;i > 0;i--)
                      factorial*=i;
                   printf("El factorial de %d es %d\n",numero_factorial,factorial);
               }
               break;
            //Detallar una tabla de multiplicar
            case TABLA_MULTIPLICAR:
               printf("Dame el multiplicando i = ");
               scanf("%d",&multiplicando);
               printf("Dame hasta cual multiplicador n= ");
               scanf("%d",&multiplicador);
               printf("Tabla de multiplicar del %d\n",multiplicador);
               i = 1;
               while(i <= multiplicador)
               {
                   printf("%d\tX\t%d\t=\t%d\n",multiplicando,i,multiplicando*i);
                   i++;
               }
               break;
            //Salida del programa
            case SALIR:
               continuar = 0;
               break;
            default:
               printf("Opcion no valida!\n");
        }
        if(continuar)
           system("pause");
    }while(continuar);
    return 0;
}


de antemano gracias

vangodp

Una función entonces :D

void obtenervalor( &variable  ){
   //aquí su código
}

:silbar:

amchacon

Se le da más importancia al buffer de la que tiene...

El error que veo ahí esque no borras la pantalla entre cada bucle. En windows es con system("CLS");

Aparte de eso. ¿Cual es el problema que tiene? Detallalo más...
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

ivancea96

Si no encuentras otra solución, lo que dijo vangodp, hacer una función para pedir la variable.
Ya en esa función, limpias el buffer, el stdin, y la habitación si quieres xD

Hasta puedes pasarle el mensaje a mostrar a la función jaja. Eso ya como tú lo decidas

Eternal Idol

Si, tenes que sacar todos, uno es suficiente para jode el buffer de ENTRADA. No confundan con la pantalla que es de salida.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Vaagish

Citartengo que cambiar cada uno de los scanf() que tengo en mi codigo por un fgets + sscanf???? lo que pasa es que son muchisimos

Cual es tu concepto de muchísimos, si el programa tiene 110 lineas?  :rolleyes:

m@o_614

#6
gracias por sus respuestas, en realidad no son tantos scanf, solo que queria ahorrarme líneas de código para que cada vez que tuviera que ingresar un dato no repitiera fgets +sscanf. Le hice unos cambios al codigo y ya funciona para todos los casos excepto para el de ARITMETICA_BINARIA, que me pide que le ingrese un operando (que es de tipo char) y en la funcion de ingresarDato, me dice que el sscanf me va a guardar  el dato en una variable de tipo int, como puedo corregir esto?? que el sscanf me pueda guardar datos tanto de tipo int como de tipo char??

#include <stdio.h>
#include <stdlib.h>
#define TAM 5
#define ARITMETICA_SIMPLE 1
#define ARITMETICA_BINARIA 2
#define FACTORIAL 3
#define TABLA_MULTIPLICAR 4
#define SALIR 5

void ingresarDato();

int main()
{
   //Variables de uso interno del programa
   int continuar = 1,i,factorial = 1;
   //Variables para entrada de datos
   int opcion,numero1,numero2,numero_factorial,multiplicando,multiplicador;
   char operador;
   do
   {
       //Menu principal
       printf("CALCULADORA v1.0\n\n");
       printf("Elige una de las siguientes opciones:\n");
       printf("1. Aritmetica simple con suma de enteros a+b\n");
       printf("2. Aritmetica extendida binaria\n");
       printf("3. Factorial de n (n!)\n");
       printf("4. Detallar una tabla de multiplicar\n");
       printf("5. Salir\n");
       printf("Opcion a elegir? ");
       ingresarDato(&opcion);
       switch(opcion)
       {
           //Aritmetica simple con suma de enteros a+b
           case ARITMETICA_SIMPLE:
              printf("Dame el valor de a = ");
              ingresarDato(&numero1);
              printf("Dame el valor de b = ");
              ingresarDato(&numero2);
              printf("%d + %d = %d",numero1,numero2,numero1+numero2);
              break;
           //Aritmetica extendida binaria (+,-,*,/,%modulo)
           case ARITMETICA_BINARIA:
              printf("Escribe el operador (+,-,*,/,%%): ");
              ingresarDato(&operador);
              printf("\nDame el valor de a = ");
              ingresarDato(&numero1);
              printf("Dame el valor de b = ");
              ingresarDato(&numero2);
              switch(operador)
              {
                  case '+':
                     printf("%d %c %d = %d\n",numero1,operador,numero2,numero1+numero2);
                     break;
                  case '-':
                     printf("%d %c %d = %d\n",numero1,operador,numero2,numero1-numero2);
                     break;
                  case '*':
                     printf("%d %c %d = %d\n",numero1,operador,numero2,numero1*numero2);
                     break;
                  case '/':
                     printf("%d %c %d = %d\n",numero1,operador,numero2,numero1/numero2);
                     break;
                  case '%':
                     printf("%d %c %d = %d\n",numero1,operador,numero2,numero1%numero2);
                     break;
                  default:
                     printf("No hay un resultado calculable\n");
                     printf("%d %c %d = 0\n",numero1,operador,numero2);
              }
              break;
           //Factorial de n (n!)
           case FACTORIAL:
              printf("Dame el valor de n = ");
              ingresarDato(&numero_factorial);
              if(numero_factorial < 0)
                 printf("El factorial de %d no esta definido\n",numero_factorial);
              else if(numero_factorial == 0)
                 printf("El factorial de 0 es 1\n");
              else
              {
                  for(i = numero_factorial;i > 0;i--)
                     factorial*=i;
                  printf("El factorial de %d es %d\n",numero_factorial,factorial);
              }
              break;
           //Detallar una tabla de multiplicar
           case TABLA_MULTIPLICAR:
              printf("Dame el multiplicando i = ");
              ingresarDato(&multiplicando);
              printf("Dame hasta cual multiplicador n= ");
              ingresarDato(&multiplicador);
              printf("Tabla de multiplicar del %d\n",multiplicador);
              i = 1;
              while(i <= multiplicador)
              {
                  printf("%d\tX\t%d\t=\t%d\n",multiplicando,i,multiplicando*i);
                  i++;
              }
              break;
           //Salida del programa
           case SALIR:
              continuar = 0;
              break;
           default:
              printf("Opcion no valida!\n");
       }
       if(continuar)
          system("pause");
   }while(continuar);
   return 0;
}

void ingresarDato(void *dato)
{
   char buffer[TAM];
   fgets(buffer,sizeof(buffer),stdin);
   sscanf(buffer,"%d",dato);
}


gracias

rir3760

* Lo primero a cambiar es el prototipo de la funciona "ingresarDato" a:
void ingresarDato(int *num);
Ya que en C los paréntesis vacíos en una declaración indican un numero indeterminado de argumentos.

* Se deben evitar los comentarios como este:
//Variables de uso interno del programa
Porque su valor como documentación es nulo, en su lugar se debe indicar la intención.

* El problema principal se debe a que tratas de leer el operador como un entero, en su lugar debes leerlo como un carácter con:
printf ("Escribe el operador (+,-,*,/,%%): ");
scanf(" %c", &operador);
{
   int ch;
   
   while ((ch = getchar()) != EOF && ch != '\n')
      ;
}


Lo anterior es solo la forma mas sencilla, lo mejor es modificar la función "ingresarDato" para que acepte dos argumentos: una dirección de memoria (de tipo "void *", esto para pasar cualquiera) y un entero que indique el tipo (int, char, etc.).

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

m@o_614

#8
entonces el primer argumento de la función ingresarDato está bien no?? porque es *void

void ingresarDato(void *dato)
{
   char buffer[TAM];
   fgets(buffer,sizeof(buffer),stdin);
   sscanf(buffer,"%d",dato);
}


ya solo le faltaria otro argumento para indicarle el tipo de dato, pero como se le puede pasar por argumento un tipo de dato y que este sea int??

ivancea96

Podrías sobrecargar la función para cada tipo de dato, por ejemplo.

Si fuera C++, podrías usar un Template.