Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: ThronerAXE en 7 Marzo 2013, 04:06 am



Título: Problema con un codigo que no funciona como debe hacerlo
Publicado por: ThronerAXE en 7 Marzo 2013, 04:06 am
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:

Código
  1. #include <stdio.h>
  2. #include <conio.h>
  3. #include <ctype.h>
  4. #include <string.h>
  5. #define MAX 50
  6.  
  7. int main()
  8. {
  9. int k,i=0,mayor=-1;
  10. float gasol_lt[MAX],rcdo[MAX],ConKmLt;
  11. char fecha[MAX][30],resp,aux[30];
  12.  
  13.  
  14.  
  15.    do
  16.    {     system("cls");
  17.          printf("\n\nFecha en que recargo el tanque de gasolina(dd/mm/aaaa): ");
  18.          fflush(stdin);
  19.          scanf("%s",&fecha[i]);
  20.          printf("\n\nCuantos litros de gasolina echo en el tanque: ");
  21.          fflush(stdin);
  22.          scanf("%f",&gasol_lt[i]);
  23.          printf("\n\nCuantos Km. recorrio: ");
  24.          fflush(stdin);
  25.          scanf("%f",&rcdo[i]);
  26.           ConKmLt=rcdo[i]/gasol_lt[i];
  27.          printf("\n\nUsted gasto %.2f km/lt",ConKmLt);
  28.          getch();
  29.          printf("\n\nDesea ingresar los datos nuevamente:...S/N ");
  30.          scanf("%c",&resp);
  31.          resp=toupper (getch());
  32.           k++;
  33.     }while(resp=='S' && i<MAX);
  34.  
  35.  
  36.    for(k=0;k<i;k++)
  37.    {    if(gasol_lt[k]>mayor)
  38.         { mayor=gasol_lt[k];
  39.           strcpy(aux,fecha[k]);        
  40.         }
  41.    }
  42.    printf("\n\n\nLa Fecha en que recargo mas gasolina fue %s",aux);
  43.    getch();
  44. }
  45.  
  46.  

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!


Título: Re: Problema con un codigo que no funciona como debe hacerlo
Publicado por: rir3760 en 7 Marzo 2013, 04:17 am
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| (http://foro.elhacker.net/programacion_cc/lo_que_no_hay_que_hacer_en_cc_nivel_basico-t277729.0.html).

Un saludo


Título: Re: Problema con un codigo que no funciona como debe hacerlo
Publicado por: ThronerAXE en 8 Marzo 2013, 03:49 am
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?.


Título: Re: Problema con un codigo que no funciona como debe hacerlo
Publicado por: leosansan en 8 Marzo 2013, 07:42 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| (http://|Lo que no hay que hacer en C/C++. Nivel basico|)

Saluditos!. ...(http://st.forocoches.com/foro/images/smilies/ciao.gif)


Título: Re: Problema con un codigo que no funciona como debe hacerlo
Publicado por: amchacon en 8 Marzo 2013, 15:26 pm
podria 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
  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <string.h>
  4. #define MAX 50
  5.  
  6. void LimpiarBuffer()
  7. {
  8.    while(getchar() != '\n' && getchar() != EOF);
  9. }
  10.  
  11. int main()
  12. {
  13. int k,i=0,mayor=-1;
  14. float gasol_lt[MAX],rcdo[MAX],ConKmLt;
  15. char fecha[MAX][30],resp,aux[30];
  16.  
  17.    do
  18.    {     system("cls");
  19.          printf("\n\nFecha en que recargo el tanque de gasolina(dd/mm/aaaa): ");
  20.          scanf("%s",&fecha[i]);
  21.          LimpiarBuffer();
  22.          printf("\n\nCuantos litros de gasolina echo en el tanque: ");
  23.  
  24.          scanf("%f",&gasol_lt[i]);
  25.          LimpiarBuffer();
  26.          printf("\n\nCuantos Km. recorrio: ");
  27.  
  28.          scanf("%f",&rcdo[i]);
  29.          LimpiarBuffer();
  30.           ConKmLt=rcdo[i]/gasol_lt[i];
  31.          printf("\n\nUsted gasto %.2f km/lt",ConKmLt);
  32.          getchar();
  33.          printf("\n\nDesea ingresar los datos nuevamente:...S/N ");
  34.          scanf("%c",&resp);
  35.          resp=getchar();
  36.           i++;
  37.     }while(resp=='S' && i<MAX);
  38.  
  39.  
  40.    for(k=0;k<i;k++)
  41.    {    if(gasol_lt[k]>mayor)
  42.         { mayor=gasol_lt[k];
  43.           strcpy(aux,fecha[k]);        
  44.         }
  45.    }
  46.    printf("\n\n\nLa Fecha en que recargo mas gasolina fue %s",aux);
  47.    getchar();
  48.    getchar();
  49. }


Título: Re: Problema con un codigo que no funciona como debe hacerlo
Publicado por: ThronerAXE en 9 Marzo 2013, 04:04 am
Código
  1. #include <stdio.h>
  2. void LimpiarBuffer()
  3. {
  4.    while(getchar() != '\n' && getchar() != EOF);
  5. }
  6.  
Que significa esto? y porque al dar la salida en la linea 46 pones getchar() 2 veces consecutivas?


Título: Re: Problema con un codigo que no funciona como debe hacerlo
Publicado por: amchacon en 9 Marzo 2013, 12:11 pm
Código
  1. #include <stdio.h>
  2. void LimpiarBuffer()
  3. {
  4.    while(getchar() != '\n' && getchar() != EOF);
  5. }
  6.  
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í:

Código
  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <string.h>
  4. #define MAX 50
  5.  
  6. int main()
  7. {
  8. int k,i=0,mayor=-1;
  9. float gasol_lt[MAX],rcdo[MAX],ConKmLt;
  10. char fecha[MAX][30],resp,aux[30];
  11.  
  12.    do
  13.    {     system("cls");
  14.          printf("\n\nFecha en que recargo el tanque de gasolina(dd/mm/aaaa): ");
  15.          scanf("%s",&fecha[i]);
  16.          while(getchar() != '\n' && getchar() != EOF);
  17.          printf("\n\nCuantos litros de gasolina echo en el tanque: ");
  18.  
  19.          scanf("%f",&gasol_lt[i]);
  20.          while(getchar() != '\n' && getchar() != EOF);
  21.          printf("\n\nCuantos Km. recorrio: ");
  22.  
  23.          scanf("%f",&rcdo[i]);
  24.          while(getchar() != '\n' && getchar() != EOF);
  25.           ConKmLt=rcdo[i]/gasol_lt[i];
  26.          printf("\n\nUsted gasto %.2f km/lt",ConKmLt);
  27.          getchar();
  28.          printf("\n\nDesea ingresar los datos nuevamente:...S/N ");
  29.          scanf("%c",&resp);
  30.          resp=getchar();
  31.           i++;
  32.     }while(resp=='S' && i<MAX);
  33.  
  34.  
  35.    for(k=0;k<i;k++)
  36.    {    if(gasol_lt[k]>mayor)
  37.         { mayor=gasol_lt[k];
  38.           strcpy(aux,fecha[k]);        
  39.         }
  40.    }
  41.    printf("\n\n\nLa Fecha en que recargo mas gasolina fue %s",aux);
  42.    getchar();
  43.    getchar();
  44. }

En cuanto al significado de esto:

Código
  1. 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).

y 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.


Título: Re: Problema con un codigo que no funciona como debe hacerlo
Publicado por: rir3760 en 9 Marzo 2013, 18:21 pm
Un problema con la función:
Código
  1. void LimpiarBuffer()
  2. {
  3.   while(getchar() != '\n' && getchar() != EOF);
  4. }
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:
Código
  1. void LimpiarBuffer(void)
  2. {
  3.   int ch;
  4.  
  5.   while ((ch = getchar()) != '\n' && ch != EOF)
  6.      ;
  7. }

Un saludo


Título: Re: Problema con un codigo que no funciona como debe hacerlo
Publicado por: leosansan en 9 Marzo 2013, 23:18 pm
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:


Título: Re: Problema con un codigo que no funciona como debe hacerlo
Publicado por: ThronerAXE en 11 Marzo 2013, 03:59 am
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.

Código
  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #define MAX 50
  4. int main()
  5. {
  6.    int expediente[MAX],econo[MAX], rsdncl[MAX],i=0,k,ban,aux;
  7.    char beca[MAX],resp;
  8.  
  9.     do
  10.     {
  11.           system("cls");
  12.           printf("\n\nIngrese el numero del expediente del estudiante: ");
  13.           scanf("%d",&expediente[i]);
  14.           printf("\n\nIngrese el indice economico del estudiante(del 1 al 100): ");
  15.           scanf("%d",&econo[i]);
  16.           printf("\n\nIngrese el indice residencial del estudiante(del 1 al 100): ");
  17.           scanf("%d",&rsdncl[i]);
  18.            if(econo[i]<40 && rsdncl[i]<35)
  19.               beca[i]='A';
  20.            else
  21.               if(econo[i]<65 && rsdncl[i]<60)
  22.                   beca[i]='B';
  23.               else
  24.                   beca[i]='C';
  25.           printf("\n\nAlgun estudiante quiere solicitar la beca del comedor:..S/N? ");
  26.           scanf("%c",&resp);    
  27.           resp=toupper(getchar());
  28.          i++;
  29.     }while(resp=='S');
  30.  
  31.     system("cls");
  32.     printf("\n\nIngrese el No. del expediente a consultar: ");
  33.     scanf("%d",&aux);
  34.     k=0;
  35.  
  36.      do
  37.      {
  38.          if(aux==expediente[k])
  39.          {  printf("\n\nEl expediente %d tiene una beca de tipo %c",expediente[k],beca[k]);
  40.             getch();
  41.             break;
  42.          }
  43.          else
  44.            ++k;
  45.      }while(ban && k<i);
  46.  
  47.      if(ban)
  48.      {printf("\n\nEl Expediente buscado no existe!!! ");
  49.       getch();
  50.      }
  51. }

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:
Código
  1.      do
  2.      {
  3.          if(aux==expediente[k])
  4.          {  printf("\n\nEl expediente %d tiene una beca de tipo %c",expediente[k],beca[k]);
  5.             getch();
  6.             break;
  7.          }
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


Título: Re: Problema con un codigo que no funciona como debe hacerlo
Publicado por: leosansan en 11 Marzo 2013, 05:28 am
.........................................................................
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. 

No es una función del C es algo que se  implementa por el usuario   y se usa para paliar la falta de una variable tipo bool en C, a diferencia del C++ que sí la incorpora. Por eso la tienes mal implementada en el código. En esencia funciona cuando le asignamos el valor 0 si ocurre tal cosa o el valor 1 si ocurre esta otra cosa  luego, según el valor 0 o 1 que tenga tomamos una decisión u otra, pero eres tú el que en el código tienes que implementar todo eso.

Citar
Otro temita que entiendo es por que en esta parte del codigo:
Código
  1.      do
  2.      {
  3.          if(aux==expediente[k])
  4.          {  printf("\n\nEl expediente %d tiene una beca de tipo %c",expediente[k],beca[k]);
  5.             getch();
  6.             break;
  7.          }
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..........................

Eso es porque tienes mal implementada la variable ban, por ejemplo:

Código
  1. k=0;
  2.    ban=0;
  3.      do
  4.      {
  5.          system("cls");
  6.            printf("\n\nIngrese el No. del expediente a consultar: ");
  7.            scanf("%d",&aux);
  8.          if(aux==expediente[k])
  9.          {  printf("\n\nEl expediente %d tiene una beca de tipo %c",expediente[k],beca[k]);
  10.            ban=1;
  11.          }
  12.          else
  13.            ++k;
  14.      }while( !ban && k<i);
  15.     if (!ban)
  16.        printf("\n\nEl Expediente buscado no existe!!! ");

Saluditos!. ...(http://i1280.photobucket.com/albums/a497/leosansan/19hola-adios_zpsb6d93aee.gif)