Problema con un codigo que no funciona como debe hacerlo

Iniciado por ThronerAXE, 7 Marzo 2013, 04:06 AM

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

ThronerAXE

Buenas !

tengo un problemita. Veran me estoy iniciando en el mundo de la programacion, y de momento estoy aprendiendo cosas basicas del lenguaje C. Tengo un ejercicio que debo con arreglos unidimencionales,  y al final debo hacer una busqueda de un mayor. El problema viene con que el programa me compila normal, pero cuando lo voy a correr, me lee los datos bien, pero cuando va a dar la salida del mayor me salen letras raras o aveces no me sale nada. Este es el codigo:

#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
#define MAX 50

int main()
{
int k,i=0,mayor=-1;
float gasol_lt[MAX],rcdo[MAX],ConKmLt;
char fecha[MAX][30],resp,aux[30];



   do
   {     system("cls");
         printf("\n\nFecha en que recargo el tanque de gasolina(dd/mm/aaaa): ");
         fflush(stdin);
         scanf("%s",&fecha[i]);
         printf("\n\nCuantos litros de gasolina echo en el tanque: ");
         fflush(stdin);
         scanf("%f",&gasol_lt[i]);
         printf("\n\nCuantos Km. recorrio: ");
         fflush(stdin);
         scanf("%f",&rcdo[i]);
          ConKmLt=rcdo[i]/gasol_lt[i];
         printf("\n\nUsted gasto %.2f km/lt",ConKmLt);
         getch();
         printf("\n\nDesea ingresar los datos nuevamente:...S/N ");
         scanf("%c",&resp);
         resp=toupper (getch());
          k++;
    }while(resp=='S' && i<MAX);
   
   
   for(k=0;k<i;k++)
   {    if(gasol_lt[k]>mayor)
        { mayor=gasol_lt[k];
          strcpy(aux,fecha[k]);        
        }
   }
   printf("\n\n\nLa Fecha en que recargo mas gasolina fue %s",aux);
   getch();
}



Utilizo el compilador Dev C++, pero el programa esta en C. He leido algunos post para ir tomando algunos tips para hacerlo mejor. Pero me gustaria que me dijeron si asi como esta ese codigo esta bien, o se puede hacer mejor, porque por ejemplo yo no veo la diferencia de usar el fflush(stdin) en los codigos, porque si los omitiera el programa corre normal, aunque los coloco porque lei que era recomendable que se usaran, pero no entendi muy bien porque. Bueno de momento es todo, gracias!

rir3760

El error principal en el programa es incrementar la variable "k" dentro del bucle cuando deberías incrementar la variable "i".

No se recomienda el uso de la biblioteca conio de Borland como tampoco "fflush(stdin)", las razones de ello se describen en el tema |Lo que no hay que hacer en C/C++. Nivel basico|.

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

ThronerAXE

ups! envie el codigo mal. bueno lo de incrementar la variable antes lo tenia bien solamente que me puse creativo y comense a mover variables de un lado a otro a ver si me funcionaba. lo que me estaba causando el problema era la libreria conio.h pero entonces si decidiera meter este codigo con Builder, podria usar conio.h y la funcion fflush(stdin) sin problemas?.

leosansan

Cita de: ThronerAXE en  8 Marzo 2013, 03:49 AM
...............................................
lo que me estaba causando el problema era la libreria conio.h pero entonces si decidiera meter este codigo con Builder, podria usar conio.h y la funcion fflush(stdin) sin problemas?.

Cambiando la variable k por i, como te comentó rir, el programa runciona en principio O.K.

Lo que sucede es que en sentido estricto están de mas la librería conio y el uso de getch por no formar parte del estandar del C, así como el uso de la función fflush (stdin) por poder provocar resultados imprevistos. Más información en|Lo que no hay que hacer en C/C++. Nivel basico|

Saluditos!. ...

amchacon

Cita de: ThronerAXE en  8 Marzo 2013, 03:49 AMpodria usar conio.h y la funcion fflush(stdin) sin problemas?.
No hay ninguna tarea ni problema en el cual sea necesaria la conio.h. Dado que es una librería no estándar que solo funciona en Windows, conviene a usar las librerías estandares...

Con el fflush(stdin) pasa lo mismo, solo funciona en Windows. Conviene usar otra opción más internacional (para cualquier sistema operativo). Este sería tu código corregido:

Código (cpp) [Seleccionar]
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX 50

void LimpiarBuffer()
{
   while(getchar() != '\n' && getchar() != EOF);
}

int main()
{
int k,i=0,mayor=-1;
float gasol_lt[MAX],rcdo[MAX],ConKmLt;
char fecha[MAX][30],resp,aux[30];

   do
   {     system("cls");
         printf("\n\nFecha en que recargo el tanque de gasolina(dd/mm/aaaa): ");
         scanf("%s",&fecha[i]);
         LimpiarBuffer();
         printf("\n\nCuantos litros de gasolina echo en el tanque: ");
         
         scanf("%f",&gasol_lt[i]);
         LimpiarBuffer();
         printf("\n\nCuantos Km. recorrio: ");
         
         scanf("%f",&rcdo[i]);
         LimpiarBuffer();
          ConKmLt=rcdo[i]/gasol_lt[i];
         printf("\n\nUsted gasto %.2f km/lt",ConKmLt);
         getchar();
         printf("\n\nDesea ingresar los datos nuevamente:...S/N ");
         scanf("%c",&resp);
         resp=getchar();
          i++;
    }while(resp=='S' && i<MAX);


   for(k=0;k<i;k++)
   {    if(gasol_lt[k]>mayor)
        { mayor=gasol_lt[k];
          strcpy(aux,fecha[k]);        
        }
   }
   printf("\n\n\nLa Fecha en que recargo mas gasolina fue %s",aux);
   getchar();
   getchar();
}
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

ThronerAXE

Código (cpp) [Seleccionar]
#include <stdio.h>
void LimpiarBuffer()
{
   while(getchar() != '\n' && getchar() != EOF);
}

Que significa esto? y porque al dar la salida en la linea 46 pones getchar() 2 veces consecutivas?

amchacon

Cita de: ThronerAXE en  9 Marzo 2013, 04:04 AM
Código (cpp) [Seleccionar]
#include <stdio.h>
void LimpiarBuffer()
{
   while(getchar() != '\n' && getchar() != EOF);
}

Que significa esto? y porque al dar la salida en la linea 46 pones getchar() 2 veces consecutivas?
Mmm... ¿Has dado las funciones?

Una función es un trozo de código que se guarda bajo un nombre y que se puede ejecutar. Realmente, podríamos eliminar la función y poner algo así:

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX 50

int main()
{
int k,i=0,mayor=-1;
float gasol_lt[MAX],rcdo[MAX],ConKmLt;
char fecha[MAX][30],resp,aux[30];

    do
    {     system("cls");
          printf("\n\nFecha en que recargo el tanque de gasolina(dd/mm/aaaa): ");
          scanf("%s",&fecha[i]);
          while(getchar() != '\n' && getchar() != EOF);
          printf("\n\nCuantos litros de gasolina echo en el tanque: ");

          scanf("%f",&gasol_lt[i]);
          while(getchar() != '\n' && getchar() != EOF);
          printf("\n\nCuantos Km. recorrio: ");

          scanf("%f",&rcdo[i]);
          while(getchar() != '\n' && getchar() != EOF);
           ConKmLt=rcdo[i]/gasol_lt[i];
          printf("\n\nUsted gasto %.2f km/lt",ConKmLt);
          getchar();
          printf("\n\nDesea ingresar los datos nuevamente:...S/N ");
          scanf("%c",&resp);
          resp=getchar();
           i++;
     }while(resp=='S' && i<MAX);


    for(k=0;k<i;k++)
    {    if(gasol_lt[k]>mayor)
         { mayor=gasol_lt[k];
           strcpy(aux,fecha[k]);       
         }
    }
    printf("\n\n\nLa Fecha en que recargo mas gasolina fue %s",aux);
    getchar();
    getchar();
}


En cuanto al significado de esto:

while(getchar() != '\n' && getchar() != EOF);

Es un sustituto más elegante del fflush(stdin). Cuando tu insertas un dato no adecuado en un scanf (por ejemplo, pedía un int y insertas un char) puede dar a lugar a desbordamientos de buffer ya que se salta el salto del enter... No te digo nada, pruebalo tu mismo.

Lo que hace ese código, es ir tomando caracteres con getchar() hasta que volvamos a llegar a la tecla intro de nuevo (\n). Por seguridad adicional, también he puesto el EOF (ocurriría si agotaramos el buffer de escritura, cosa poco probable).

Cita de: ThronerAXE en  9 Marzo 2013, 04:04 AMy porque al dar la salida en la linea 46 pones getchar() 2 veces consecutivas?
Pongo el getchar como sustituto del getch... Y lo pongo dos veces por si acaso xD.
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

rir3760

Un problema con la función:
void LimpiarBuffer()
{
   while(getchar() != '\n' && getchar() != EOF);
}

Supongamos que el resto de la linea es 'a', '\n'. La primera llamada descarta el carácter 'a' y la segunda el carácter '\n' (ahí el problema). En la segunda iteracion del bucle getchar espera un carácter y este debe ser un avance de linea (de no ser así el bucle continua).

Para evitarlo se debe leer un carácter por iteracion comparando este contra las dos constantes:
void LimpiarBuffer(void)
{
   int ch;
   
   while ((ch = getchar()) != '\n' && ch != EOF)
      ;
}


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

leosansan

De todas formas, si sólo se trata de eliminar un posible carácter creo más razonable el dejar un espacio en blenco en el scanf, como ya comentamos en otro tema,

Saluditos!
.... :silbar:

ThronerAXE

Gracias por sus consejos. tengo este nuevo problema xd
Este programa debe pedirle a unos estudiantes 2 indices diferentes que determinaran una beca para ellos, ademas al final el programa debe buscar a los estudiantes y decirle la beca que tendran. El programa funciona bien pero al momento de buscar, en el caso de que el estudiante exista, me da la salida de la beca que le corresponde y luego sale la salida como si el estudiante no existiera :S este es el codigo.

#include <stdio.h>
#include <ctype.h>
#define MAX 50
int main()
{
    int expediente[MAX],econo[MAX], rsdncl[MAX],i=0,k,ban,aux;
    char beca[MAX],resp;
   
     do
     {
           system("cls");
           printf("\n\nIngrese el numero del expediente del estudiante: ");
           scanf("%d",&expediente[i]);
           printf("\n\nIngrese el indice economico del estudiante(del 1 al 100): ");
           scanf("%d",&econo[i]);
           printf("\n\nIngrese el indice residencial del estudiante(del 1 al 100): ");
           scanf("%d",&rsdncl[i]);
            if(econo[i]<40 && rsdncl[i]<35)
               beca[i]='A';
            else
               if(econo[i]<65 && rsdncl[i]<60)
                   beca[i]='B';
               else
                   beca[i]='C';
           printf("\n\nAlgun estudiante quiere solicitar la beca del comedor:..S/N? ");
           scanf("%c",&resp);   
           resp=toupper(getchar());
          i++;
     }while(resp=='S');
     
     system("cls");
     printf("\n\nIngrese el No. del expediente a consultar: ");
     scanf("%d",&aux);
     k=0;
     
      do
      {
          if(aux==expediente[k])
          {  printf("\n\nEl expediente %d tiene una beca de tipo %c",expediente[k],beca[k]);
             getch();
             break;
          }
          else
            ++k;
      }while(ban && k<i);
     
      if(ban)
      {printf("\n\nEl Expediente buscado no existe!!! ");
       getch();
      }
}


lo de "ban" significa banderas que me lo dieron en la universidad que significa que cuando la bandera vale 0 es falso y cuando vale 1 o es diferente de 0 es verdadero.  He buscado ese tema por internet para estudiar un poco esta funcion pero no lo consigo.

Otro temita que entiendo es por que en esta parte del codigo:
      do
      {
          if(aux==expediente[k])
          {  printf("\n\nEl expediente %d tiene una beca de tipo %c",expediente[k],beca[k]);
             getch();
             break;
          }

la parte del "break" lo tuve que incluir porque si no lo incluia, al momento de dar la salida de la beca del estudiante, la da pero nunca terminaba. Cada vez que le doy enter, el programa me volvia a dar la salida, pero no tengo del todo claro porque metiendo el break si me funciona. Alguien que porfavor me explique :) xD