Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: NOB2014 en 11 Enero 2014, 18:16 pm



Título: Limpieza de buffer de teclado en lenguaje C.
Publicado por: NOB2014 en 11 Enero 2014, 18:16 pm
Hola.
Cuando ingreso más de 3 cifras todo funciona a la perfección, pero si ingreso menos de 4 el programa se queda detenido en el bucle while de limpieza de buffer de teclado, es como cuando tiene algo para leer (más de 3 cifras) todo funciona Ok .-

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main(void){
  5. unsigned int ok=0, ch=0, longitud=0;
  6. char numeroChar[7] = "";
  7.  
  8. do{
  9. system("cls");
  10. printf("\n\n Ingrese un entero....:");
  11. fgets(numeroChar, 5, stdin);
  12. longitud = strlen(numeroChar);
  13. while((ch = getchar()) != '\n');
  14. numeroChar[longitud-1] = '\0';
  15. printf("\n\n Ingresaste..: %s   -----> longitud = %d", numeroChar, longitud);
  16. printf("\n\n 0 para continuar otro para salir....:");
  17. scanf("%d" , &ok);
  18. while((ch = getchar()) != '\n');
  19. }while(ok==0);
  20.  
  21. return 0;
  22. }
   

Bueno espero que me ayuden porque hace 2 días que estoy googleando y practicando y no logro la solución y por favor un poco de teoría del porqué.-       

Saludos.



Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: vangodp en 11 Enero 2014, 22:09 pm
No se si es eso que lo quieres  :rolleyes:
Código
  1.    #include <stdio.h>
  2.    #include <stdlib.h>
  3.    #include <string.h>
  4.  
  5.    int main(void){
  6.     unsigned int ok=0, ch=0, longitud=0;
  7.     char numeroChar[7] = "";
  8.  
  9.     do{
  10.     system("cls");
  11.     printf("\n\n Ingrese un entero....:");
  12.     scanf("%s",&numeroChar);
  13.     longitud = strlen(numeroChar);
  14.  
  15.     while((ch = getchar()) != '\n')
  16.     numeroChar[longitud-1] = '\0';
  17.     printf("\n\n Ingresaste..: %s   -----> longitud = %d", numeroChar, longitud);
  18.     printf("\n\n 0 para continuar otro para salir....:");
  19.     scanf("%d" , &ok);
  20.     while((ch = getchar()) != '\n');
  21.  
  22.  
  23.     }while(ok==0);
  24.  
  25.    return 0;
  26.    }
  27.  


Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: NOB2014 en 11 Enero 2014, 23:06 pm
Hola vangodp.
Por el momento solo me limito a leer y no tengo argumentos para disentir en ciertas cosas por el poco tiempo que tengo estudiando C.-
Sólo voy a hacer unas pequeñas observaciones:
En primer lugar tengo leído que la única función que debo utilizar para leer cadenas es fgets y más en este caso que necesito un máximo restringido de caracteres ingresados.-
En segundo lugar si ingreso 12345678 el resultado es incorrecto.-

(http://i43.tinypic.com/2cpzwjc.jpg)

Luego de lo observado el programa funciona muy bien.-
De cualquier manera en este instante encontré la solución.-   

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main(void){
  5. unsigned int ok=0, ch=0, c=0, longitud=0;
  6. char numeroChar[7] = "";
  7.  
  8. do{
  9. system("cls");
  10. printf("\n\n Ingrese un entero....:");
  11. fgets(numeroChar, 5, stdin);
  12. longitud = strlen(numeroChar);
  13.  
  14. do{
  15. if(ch == 0) break;
  16. }while((ch = getchar()) != '\n');
  17.  
  18. numeroChar[longitud-1] = '\0';
  19. printf("\n\n Ingresaste..: %s   -----> longitud = %d", numeroChar, longitud);
  20. printf("\n\n 0 para continuar otro para salir....:");
  21. scanf("%d" , &ok);
  22. while((c = getchar()) != '\n');
  23.  
  24.  
  25. }while(ok==0);
  26.  
  27. return 0;
  28. }
        

   Saludos.


Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: vangodp en 12 Enero 2014, 03:53 am
;) muy bien pues.
Suerte!


Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: leosansan en 12 Enero 2014, 04:31 am
;) muy bien pues.
Suerte!

Pues no, no está solucionado.

En tu caso, amigo vangodp, si limitas el número de caracteres  con:


Código
  1. scanf ("%5s",numeroChar);
  2.  

SI FUNCIONA.

Y en el caso de NOB2014 ni flores:


Citar

 Ingrese un entero....:123


 Ingresaste..: 123   -----> longitud = 4

 0 para continuar otro para salir....:0


 Ingrese un entero....:12345


 Ingresaste..: 123   -----> longitud = 4

 0 para continuar otro para salir....:
Process returned 0 (0x0)   execution time : 5.255 s
Press any key to continue.


¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)

REEDITADO.


Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: vangodp en 12 Enero 2014, 04:54 am
La verdad no lo eh mirado jaja
Me lo creo en su palabra, pero no se por que la gente dice cosas que no son :/
1º a mi si me funciona mi código bien.
Y aquí esta la prueba.
(http://imageshack.com/a/img513/6606/sm8j.png)

2º los detractores de Dev c++ lo van a atacar creyendo que me importa si a ellos no les gusta por que les mola mas el codeblocks.

3º por si no lo han visto el código lo comparto como cpp "SIEMPRE".
No es que lo quiera es que asi me lo guarda y no pretendo cambiar por que no programo en c.
A lo mejor por eso lo del error aun que no lo se el porque.
Supongo que por que en c el caracter final de una cadena es '\0' o eso creo, desconozco si eso es igual en c++

Por lo que fgets se usa para leer de archivo.

La solución puede que poco ortodoxa XD si imprimes 1234 y te dice 5 imprime la cadena-1 XD

Mira que pena jaja

Saludos leo, como dije antes si me equivoco perdón pues ^^
Veo que todo lo que hago tengo que poner fotos sino la gente no me cre XD


Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: vangodp en 12 Enero 2014, 05:00 am
Ahora aquí pensando conmigo el código de NOB2014 me tiraba error.
Lo solucione poniendo la librería string.h antes de venir a dar espadadas en el foro.
Lo digo por si no lo habían notado XD
Puede que sea por eso.
Pero os dire la verdad XD
No tengo ni p**a idea por lo que es, puse un cin y me funciono perfecto, lo cambie por un scanf y va que palante.
Si no le mola la solución no puedo hacer na por que no consigo hace de su manera.
Solo me queda decir suerteeeee y hasta prontoooo!  :rolleyes:

PD: NO PIENSO EN CAMBIAR A CODEBLOCKS, ya os dije antes jajaj
Lo tengo instalado, cada vez que compilo el código en codeblocks me dice lo mismo.
Me parece que la gente es como un lorito(repite to lo que ha leído por ahí sin ni saber lo que dice)
No lo niego que pueda tener problemas, ni que no sea un colisionador de partículas como lo es codeblocks ><
Pero en vez de criticar devc++ y decir oye bahhh hombre dev c++ es una caca...¡cambiate ya! XD
A ver que me deen una lista de defectos que me obligue a cambiar.
Para los que dicen que esta desactualizado les diré que esta al día la versión de orwell.
Entonces algunos loritos van a decir que aun así la versión de owell es mala, pero como siempre no aportan nada ni ningún motivo(eso se debe por que lo han leído por ahí no se donde....blablabla).
Y por eso continuare utilizando Dev c++, si queréis que cambie van a tener que currar mas  :silbar:
Para los que dicen "desactualizado" os diré que esta es la ultima fecha November 5, 2013. Como ves no es tan desactualizado así.
Repito 1000 pares de veces, no soy veterano pero a mi Dev aun no me dejo tirado, el codeblocks lo tengo para ver si el código compila en ambos y "siempre a sido correcto" lo mismo en uno que con otro.
Ahora seria injusto que no os dijera el por que uso dev en vez de code: El Dev es una bala, le hago doble click y se abre, no como codeblocks que le abro y voy a tomar un café de tan bueno que es XD
Como digo siempre siempre siempre, ya os eh expuesto mis motivos por que lo utiliso.
Ahora hacer un favor si alguien "sabe"(no loritos, ni colisionadores de partículas o navajas suizas aparte).
Me pone de los nervios mil iconos por todas las partes para funciones extras, y me gusta que el programa responda.
Si de verdad sabeis el por que NO debo utilisar dev os diré lo que digo siempre"Soy todo oídos".
Ignoro las diferencias que tenga entre uno y otro, y eso no me va hacer mejor persona.
Cuando abro un IDE quiero programar y no tirar media hora configurando cosas XD
 ;-)

(http://i690.photobucket.com/albums/vv267/USUI/FUNNY/MichaelJacksonJackson_popcorn.gif)


Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: leosansan en 12 Enero 2014, 06:57 am


Pues si que funciona. Fue un error mío ya que al pedirme la opción de introducir el cero introduje el número directamente y, claro como no empezaba con cero se cerro el programa. la verdad es que me extrañaba que el scanf fallara seguido del while para limpiar el buffer, ya que lo he hecho multitud de veces.

Pero al César lo que es del César, ya reedité el post anterior.
¿por qué guardas como .cpp lo que son en realidad códigos .c?. No cuesta tanto cuando te pide guardar, que por defecto sale ,cpp, quitarle las dos p y tenerlo así en c como corresponde. Claro que si es por comodidad nada que objetar.

Y lo del Code::Blocks es para hablar más despacio y con tiempo. Sólo el mero hecho de usar múltiples ventanitas dentro de la ventana del propio Code::Blocks y con múltiples pestañitas a la vez en cada ventanita me vale. Para que te hagas una idea, yo suelo tener más de 30 códigos abiertos al mismo tiempo, con la comodidad de tenerlos repartidos en ventanitas y pestañitas diferentes, lo que me facilita el acceso a cada código. Por no hablar de las interioridades que ya sería un tema más prolijo y/o extenso.


¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: vangodp en 12 Enero 2014, 08:12 am
No eh probado lo de las divisiones.
¿Cuantas la puede abrir?
Suelo usar lo básico de un editor, de echo uso el notepad++ por que tiene buenas funciones de edición, creo que como editor supera a todos los demás pero a pesar de poder compilar deja mucho que desear as veces tengo el texto abierto en ambos y me paso de uno a otro según el problema.
Una de las cosas que me gusta es por ejemplo escribir varias lineas a la vez, las macros y otras cosillas mas, lo tiene muy a mano.
¿Como se utiliza lo de las ventanas múltiples?Digo la división de ventanas.
¿Cuantas divisiones puede hacer el codeblocks y como se hace?
Estoy probando el editor emacs, es muy potente pero no me muevo tan suelto como en notepad++, pero ya llego ahí también con tiempo. :D
Eh probado el vim y lo de los modos no me gusto mucho, y miles de comandos no se me entra en la cabeza jeje
Prefiero partir la muñeca con las combinaciones  :laugh:
Saludos ^^


Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: vangodp en 12 Enero 2014, 08:23 am
Citar
¿por qué guardas como .cpp lo que son en realidad códigos .c?
Por que le doy al iconito del disquete.
Se me olvida usar el "guardar como" y elegir .c
Pero mirar como comparto el código como c++, eso si lo tengo claro.
Supongo que causa algunos problemas de compatibilidad, por que el compilador usa el g++ envés de gcc creo.
Yo no suelo usar funciones de c aun que hay veces que no hay mas remedio. Pero si puedo evitar mejor, si lo guardo como cpp puedo usar c pero no al contrario.
Tengo que prestar mas atención en eso, por que cuando pongo aquí el código me suele pasar eso.
Me gusta el c bastante, es muy claro y potente pero estoy con el c++.
Pero vosotros tenéis que fiar que cuando se comparte el código lo hago como cpp y ahi nunca me equivoco.Sino cualquier día viene uno aquí con un código en java y iréis a compilar como C  :laugh:


Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: NOB2014 en 13 Enero 2014, 00:54 am

Hola.
Por favor me podrían probar el programa para que me digan si encuentran algún    error, estoy totalmente obnubilado y necesito de mentes frescas para que constaten si  definitivamente no los tiene (más allá de que se ingresen  100 dígitos).-
       
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. void limpiar(char[], int);
  5.  
  6. int main(void){
  7. unsigned int ok=0, longitud=0, i=0, ch=0;
  8. char numeroChar[100] = "";
  9.  
  10. do{
  11. system("cls");
  12. printf("\n\n Ingrese un entero (maximo 9999)....:");
  13. fgets(numeroChar, 100, stdin);
  14. longitud = strlen(numeroChar);
  15. i=0;
  16. if(longitud >=4){
  17. limpiar(numeroChar, longitud);
  18. }
  19. longitud = strlen(numeroChar);
  20.  
  21. printf("\n\n Ingresaste..: %s", numeroChar);
  22.  
  23. printf("\n\n 0 para continuar otro para salir....:");
  24. scanf("%d" , &ok);
  25. while((ch = getchar()) != '\n');
  26.  
  27. }while(ok==0);
  28.  
  29. return 0;
  30. }
  31.  
  32. void limpiar(char numeroChar[], int longitud){
  33. int i=3;
  34. while(++i < longitud){
  35. if(i==4){
  36. numeroChar[4] = '\0';
  37. }
  38. if(i>4){
  39. numeroChar[i] = ' ';
  40. }
  41. }
  42. }

    Desde ya muchas gracias.-
    Saludos.


Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: leosansan en 13 Enero 2014, 04:35 am
No eh probado lo de las divisiones.
¿Cuantas la puede abrir?


Yo suelo tener nueve ventanitas con tropecientas pestañitas, lo que me permite comparar códigos o recordar comandos básicos de una manera rápida.

Luego amplio la ventana de trabajo actual y automáticamente se ajusta el tamaño de las demás.

Siento que las imágenes no sean muy buenas peo estoy en el portátil, en el monitor grande lo tienen ocupado en este momento. Pero bueno, como prueba de lo que digo creo que vale.

Se consigue abriendo varios ficheros a la vez y arrastrando pestañas hacia los lados. Simple pero muy eficiente:


(http://i1280.photobucket.com/albums/a497/leosansan/GRAFICOS1/Code_Blocks_zps6d42edde.jpg)


(http://i1280.photobucket.com/albums/a497/leosansan/GRAFICOS1/Code_Blocks1_zps3a8a70f0.jpg)


Y respecto a NOB2014 recordarle que  se tienen que introducir un máximo de 4 caracteres (9 9 9 9 ). El problema surge al declarar el array con tamaño 5 ya que si se introducen más cifras no caben en el array y toman valores basura. La solución es declarar, como has hecho tú, el array con más cifras por precaución, no sea que se introduzcan más de cuatro y empiece el buffer a llenarse de basura. Ya luego sólo queda limitar el tamaño de la cadena con la introducción del caracter nulo,

Te dejo una muestra:

Citar

Ingrese un entero (maximo 9999)....:123


 Ingresaste..: 123


 0 para continuar otro para salir....:0


 Ingrese un entero (maximo 9999)....:123456789


 Ingresaste..: 1234

 0 para continuar otro para salir....:0


 Ingrese un entero (maximo 9999)....:12


 Ingresaste..: 12


 0 para continuar otro para salir....:0


 Ingrese un entero (maximo 9999)....:12345


 Ingresaste..: 1234

 0 para continuar otro para salir....:


Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define N 5
  4.  
  5. int main(void){
  6. unsigned int ok=0, longitud=0, i=0, ch=0;
  7. char numeroChar[100] = "";
  8.  
  9. do{
  10. //system("cls");
  11. printf("\n\n Ingrese un entero (maximo 9999)....:");
  12. fgets(numeroChar, 100, stdin);
  13.                numeroChar[N-1] = '\0';
  14. printf("\n\n Ingresaste..: %s", numeroChar);
  15. printf("\n\n 0 para continuar otro para salir....:");
  16. scanf("%d" , &ok);
  17. while((ch = getchar()) != '\n');
  18. }while(ok==0);
  19. return 0;
  20. }
  21.  

¡¡¡¡ Saluditos! ..... !!!!

(http://i1280.photobucket.com/albums/a497/leosansan/leosan1/dancer2_zpsec8a4bbe.gif)


Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: vangodp en 13 Enero 2014, 06:57 am
Lo que andaba buscando lo encontre -_-' aun que me costo un poco XD
(http://imageshack.com/a/img839/5207/aep5.png)
Es que pulsando ctrl + ratón izquierdo o alt + ratón izquierdo puedo editar varias lineas y eso para mi es una de las mejores funciones. No se por que viene desactivada por defecto.
Ahora codeblocks++ XD
Ya logre configurarlo algo a mi gusto.
si sabes alguna pagina con explicación para mi estaría muy bien.
Saludos 


Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: leosansan en 13 Enero 2014, 07:37 am
Lo que andaba buscando lo encontre -_-' aun que me costo un poco XD
...............................................

Y mucho más que iras encontrando a medida que navegues por las opciones.

Un ejemplo es el modo automático para los bucles y más:


(http://i1280.photobucket.com/albums/a497/leosansan/GRAFICOS1/Code_Blocks2_zps33f1fb53.jpg)

(http://i1280.photobucket.com/albums/a497/leosansan/leosan2/4grandes_zps11cad90e.gif)

¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: NOB2014 en 13 Enero 2014, 15:12 pm
Hola.
Excelente simplificaste mucho mi código, muchas gracias.-

Citar
fgets Leerá hasta n-1 caracteres o hasta que lea un retorno de línea (\n).
En este último caso , el carácter de retorno de línea también es leído.-

Saludos.


Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: rir3760 en 19 Enero 2014, 03:22 am
Cuando ingreso más de 3 cifras todo funciona a la perfección
Porque si introduces como mínimo cuatro caracteres, por ejemplo:
Código:
1234{ENTER}
La función fgets al estar limitada a cinco caracteres (incluyendo el '\0') almacenara los caracteres '1', '2', '3', '4' y '\0' en el array. El carácter '\n' se queda en el bufer de la entrada estándar.

Cuando se ejecuta el bucle:
Código
  1. while ((ch = getchar()) != '\n')
  2.   ;
Este procesa el resto de la linea hasta encontrar el '\n', cuando eso sucede la condición es falsa y causa la terminación del bucle.

Por cierto el bucle esta mal, la variable "ch" debe ser de tipo "signed int" y se debe verificar si el resultado de getchar es EOF. Debería ser:
Código
  1. int ch;
  2.  
  3. /* ... */
  4.  
  5. while ((ch = getchar()) != EOF && ch != '\n')
  6.   ;

pero si ingreso menos de 4 el programa se queda detenido en el bucle while de limpieza de buffer de teclado
Porque en este escenario con un máximo de tres caracteres mas el avance de linea, por ejemplo:
Código:
123{ENTER}
La función fgets almacena todos los caracteres en el array. Cuando se ejecuta el bucle para descartar el resto de la linea no hay tal (por ello se debe teclear una linea adicional).

----

En cuanto al primer programa de vangodp este da la apariencia de no funcionar correctamente, se sostiene porque varios errores se cancelan mutuamente. Por ejemplo si se ejecuta e introduce:
Código:
123{ESPACIO}{ENTER}
Su salida es:
Código:
 Ingrese un entero....:123


 Ingresaste..: 12   -----> longitud = 3

 0 para continuar otro para salir....:
Ello porque el espacio causa que el bucle donde se descarta el resto de la linea se ejecute por lo menos una ves y con ello se pierde el ultimo carácter.

En ese programa se debe considerar que los especificadores "%s" y "%d" descartan el espacio blanco (espacio, tabulador, etc.) y por ello los bucles de soporte no son necesarios. El programa se puede reducir a:
Código
  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5.   char palabra[7];
  6.   int ok;
  7.  
  8.   do {
  9.      puts("Introduce una palabra:");
  10.      if (scanf("%s", palabra) != 1)
  11.         break;
  12.      printf("Ingresaste: %s\n", palabra);
  13.  
  14.      puts("0 para continuar otro para salir:");
  15.   }while (scanf("%d" , &ok) == 1 && ok == 0);
  16.  
  17.   return 0;
  18. }
Sin embargo "%s" se debe evitar ya que tiene el mismo defecto que la función gets (mejor utilizar "%Ns" o bien fgets).

Un saludo


Título: Re: Limpieza de buffer de teclado en lenguaje C.
Publicado por: leosansan en 20 Enero 2014, 23:37 pm
.........................
    scanf ..............
..........................


Con toda humildad y respeto, creo que tomas la tangente usando el scanf cuando de lo que se trataba era de cómo actuar ante la función fgets.

Sinceramente espero una aportación tuya que nos saque de la duda, ya que este tema ha surgido en otro tema y nos tiene con soluciones, que si bien hacen correctamente la labor, hecho de menos una solución más elegante y/o simple por parte tuya. Para que veas la alta estima en que te tengo ;)


¡¡¡¡ Saluditos! ..... !!!!


(http://st.forocoches.com/foro/images/smilies/simba1.gif)

P.D: Otro hilo que trata el tema es error_fgets (http://foro.elhacker.net/programacion_cc/error_fgets_solucionado-t407059.0.html).