Limpieza de buffer de teclado en lenguaje C.

Iniciado por NOB2014, 11 Enero 2014, 18:16 PM

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

NOB2014


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).-
       
#include <stdio.h>
#include <stdlib.h>

void limpiar(char[], int);

int main(void){
unsigned int ok=0, longitud=0, i=0, ch=0;
char numeroChar[100] = "";

do{
system("cls");
printf("\n\n Ingrese un entero (maximo 9999)....:");
fgets(numeroChar, 100, stdin);
longitud = strlen(numeroChar);
i=0;
if(longitud >=4){
limpiar(numeroChar, longitud);
}
longitud = strlen(numeroChar);

printf("\n\n Ingresaste..: %s", numeroChar);

printf("\n\n 0 para continuar otro para salir....:");
scanf("%d" , &ok);
while((ch = getchar()) != '\n');

}while(ok==0);

return 0;
}

void limpiar(char numeroChar[], int longitud){
int i=3;
while(++i < longitud){
if(i==4){
numeroChar[4] = '\0';
}
if(i>4){
numeroChar[i] = ' ';
}
}
}


    Desde ya muchas gracias.-
    Saludos.
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

leosansan

#11
Cita de: vangodp en 12 Enero 2014, 08:12 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:






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 (cpp) [Seleccionar]

#include <stdio.h>
#include <stdlib.h>
#define N 5

int main(void){
unsigned int ok=0, longitud=0, i=0, ch=0;
char numeroChar[100] = "";

do{
//system("cls");
printf("\n\n Ingrese un entero (maximo 9999)....:");
fgets(numeroChar, 100, stdin);
               numeroChar[N-1] = '\0';
printf("\n\n Ingresaste..: %s", numeroChar);
printf("\n\n 0 para continuar otro para salir....:");
scanf("%d" , &ok);
while((ch = getchar()) != '\n');
}while(ok==0);
return 0;
}


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


vangodp

Lo que andaba buscando lo encontre -_-' aun que me costo un poco XD

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 

leosansan

Cita de: vangodp en 13 Enero 2014, 06:57 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:




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



NOB2014

Hola.
Excelente simplificaste mucho mi código, muchas gracias.-

Citarfgets 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.
abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-

rir3760

Cita de: NOB2014 en 11 Enero 2014, 18:16 PMCuando ingreso más de 3 cifras todo funciona a la perfección
Porque si introduces como mínimo cuatro caracteres, por ejemplo:
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:
while ((ch = getchar()) != '\n')
   ;

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:
int ch;

/* ... */

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


Cita de: NOB2014 en 11 Enero 2014, 18:16 PMpero 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:
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:
123{ESPACIO}{ENTER}
Su salida es:
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:
#include <stdio.h>

int main(void)
{
   char palabra[7];
   int ok;
   
   do {
      puts("Introduce una palabra:");
      if (scanf("%s", palabra) != 1)
         break;
      printf("Ingresaste: %s\n", palabra);
     
      puts("0 para continuar otro para salir:");
   }while (scanf("%d" , &ok) == 1 && ok == 0);
   
   return 0;
}

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

#16
Cita de: rir3760 en 19 Enero 2014, 03:22 AM
.........................
   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! ..... !!!!



P.D: Otro hilo que trata el tema es error_fgets.