elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Curso de javascript por TickTack


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Borrar texto en la consola usando c
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Borrar texto en la consola usando c  (Leído 4,071 veces)
hergue00

Desconectado Desconectado

Mensajes: 22


Ver Perfil
Borrar texto en la consola usando c
« en: 2 Mayo 2019, 17:04 pm »

Buenas, estoy escribiendo un programa en C con visual studio que te permite definir una contraseña.
En el programa, tu a medida que vas escribiendo caracteres te va imprimiendo *, el caso es que no se como hacer que al presionar la tecla de retroceso borre el anterior asterisco, no sé si me podréis ayudar, gracias de antemano


Código
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<malloc.h>
  5. #include<conio.h>
  6. #define length 16 //Longitud máxima de la contraseña
  7.  
  8. char* Password();
  9.  
  10. void main()
  11. {
  12. char *pass1,*pass2;
  13. int cmp=1;
  14. do
  15. {
  16. printf("Introduce una clave de %d caracteres: ", length);
  17. pass1 = Password();
  18. printf("Introduce de nuevo la clave de %d caracteres: ", length);
  19. pass2 = Password();
  20. cmp = strcmp(pass1, pass2);
  21. if (cmp == 0)
  22. printf("Clave introducida correctamente!!\n");
  23. else
  24. printf("Las claves no coinciden\n");
  25. system("PAUSE");
  26. if (cmp != 0)
  27. system("CLS");
  28. } while (cmp != 0);
  29. }
  30.  
  31. char* Password()
  32. {
  33. char *pass,c = 0;
  34. int i;
  35. //Asignacion de memoria para los caracteres y '\0'
  36. pass = (char*)malloc((length)+1);
  37. if (pass == NULL)
  38. {
  39. printf("No hay memoria disponible\n");
  40. system("PAUSE");
  41. exit(1);
  42. }
  43.  
  44. //Compobacion de que como mucho tiene los caracteres que hemos indicado. Cada vez que escribes un caracter, imprime *
  45. do
  46. {
  47. i = 0;
  48.  
  49. while (c != 13) //Si no presionamos intro
  50. {
  51. if (i < 18) //Si la contraseña cabe en la cadena, se va introduciendo
  52. {
  53. c = _getch();
  54. if (c != 8 && c != 13)
  55. {
  56. pass[i] = c;
  57. printf("*");
  58. }
  59.  
  60. if (c == 8) //Pulsa retroceso
  61. {
  62. c = NULL;
  63. i = i - 2;
  64. }
  65. }
  66. else //Si no entra siemplemente se imprimen los *, luego te mandara repetir contraseña
  67. {
  68. c = _getch();
  69. if (c != 8&&c!=13)
  70. {
  71. printf("*");
  72. }
  73.  
  74. if (c == 8)
  75. {
  76. c = NULL;
  77. i = i - 2;
  78. }
  79. }
  80. if (c == 13) //Pulsa intro
  81. {
  82. if (i < ((length)+1))
  83. pass[i] = '\0';
  84. else
  85. {
  86. pass[(length)+1] = '\0';
  87. }
  88. i--;
  89. printf("\n");
  90.  
  91. }
  92. i++;
  93. }
  94. if(i>length)
  95. printf("Error de longitud, introducela de nuevo: ");
  96. c = 0;
  97. } while (i > length);
  98.  
  99. //Reasignacion de memoria para optimizar
  100. pass = (char*)realloc(pass, i * sizeof(char) + 1);
  101. return pass;
  102. free(pass);
  103. }


« Última modificación: 2 Mayo 2019, 21:14 pm por hergue00 » En línea

hergue00

Desconectado Desconectado

Mensajes: 22


Ver Perfil
Re: Borrar texto en la consola usando c
« Respuesta #1 en: 2 Mayo 2019, 19:26 pm »

Ya lo tengo!
Simplemente añadiendo un printf("\b \b"); (Con el espacio incluido) en la condición de retroceso pulsado sale.


« Última modificación: 2 Mayo 2019, 20:48 pm por hergue00 » En línea

RayR

Desconectado Desconectado

Mensajes: 243


Ver Perfil
Re: Borrar texto en la consola usando c
« Respuesta #2 en: 2 Mayo 2019, 20:29 pm »

Bueno, en realidad es "\b \b", pero supongo que sólo fue error de dedo. Veo algunos problemas con tu código, pero como no usaste etiquetas GeSHi, no sé si algunos sean sólo partes que se "comió" el foro.

Algunos detalles: ¿qué pasa si el usuario presiona y presiona y presiona retroceso muchas veces?

Luego tienes esto:
Código:
return pass;
free(pass);
El return hace que la ejecución del programa regrese a main, por lo que no tiene sentido poner instrucciones después, ya que nunca se ejecutarán. Y de cualquier forma, ese free era incorrecto. Quien llama a tu función es quien debe liberar esa memoria. Si tú la liberaras dentro de la función Password, ya no es válida. Siendo un programa tan simple y pequeño, probablemente aún así funcionaría "correctamente" (por pura suerte) pero sería un error.

El realloc está de más. Es un ejemplo perfecto de optimización prematura. Intentar ahorrarte unos pocos bytes realmente no optimiza nada (quizás hace un par de décadas y si estuvieras programando para un microcontrolador con unos pocos KB de memoria, pero hoy...) y de hecho puede ser contraproducente. Por cuestiones de eficiencia, funciones como malloc y realloc pueden reservar más memoria que la que les pides. Puede ser, por ejemplo, en bloques múltiplos de cierto número. El caso es que, sobre todo sabiendo que estás reservando sólo unos pocos bytes, es probable que realloc considere más eficiente dejar que se "desperdicien" unos pocos bytes, y decida no tocar esa memoria, con lo cual, sólo estarías complicando más tu código, llamando a una función innecesariamente, y sin ahorrarte un sólo byte. Las optimizaciones hay que hacerlas cuando realmente tengamos la necesidad, hayamos identificado un problema, y hayamos sopesado pros y contras. Hacerlas por hacerlas suele traer problemas y muy poco (normalmente ningún) beneficio.
En línea

hergue00

Desconectado Desconectado

Mensajes: 22


Ver Perfil
Re: Borrar texto en la consola usando c
« Respuesta #3 en: 2 Mayo 2019, 20:44 pm »

Si, ha sido un error al escribir.

Lo del return me he dado cuenta luego, y el free(pass) en el código lo he quitado. ¿Dices que debería liberarla en el main() que es desde donde la llamo?

Respecto a lo de realloc, la verdad no lo sabía, lo había metido porque el código es parte de un trabajo para la universidad, que estamos aprendiendo a programar C, y estaba probando las funciones de asignación dinámica. Si me dices que si no me ahorro mucha memoria puede ser contraproducente, mejor lo quito.

Lo del retroceso... Cuando me lo has dicho, lo he probado y he borrado todo el mensaje de la consola me he reído la verdad jeje. Creo que lo he solucionado poniendo:

Código
  1. if(i==0&&c==8)
  2.   continue;


Debajo justo del primer "c=_getch();" (Línea 53).
« Última modificación: 2 Mayo 2019, 21:15 pm por hergue00 » En línea

RayR

Desconectado Desconectado

Mensajes: 243


Ver Perfil
Re: Borrar texto en la consola usando c
« Respuesta #4 en: 2 Mayo 2019, 21:15 pm »

Respecto a lo de realloc, la verdad no lo sabía, lo había metido porque el código es parte de un trabajo para la universidad, que estamos aprendiendo a programar C, y estaba probando las funciones de asignación dinámica. Si me dices que si no me ahorro mucha memoria puede ser contraproducente, mejor lo quito.

Si es por practicar, lo puedes dejar. No va a fallar ni a darte problemas. Simplemente te decía que cuando hablamos de cosas tan simples, como unos pocos bytes, normalmente no vale la pena intentar optimizar. El realloc perfectamente puede decidir no cambiar nada, es decir, no "reducir" la memoria, y simplemente dejar todo como está. Es perfectamente válido y tu programa funcionará sin problemas, pero en ese caso estarías haciendo esa llamada de forma innecesaria (a eso me refería con contraproducente: estás trabajando de más, posiblemente sin beneficio).

Es simplemente un consejo general, que antes de optimizar hay que revisar bien lo que hacemos. Muchas veces una "optimización" hecha sin análisis, puede incluso hacer que un programa tenga un rendimiento peor al que tenía antes de la supuesta optimización. Pero te repito, como práctica no hay problema. Cuando tengas más experiencia ya sabrás cuándo vale la pena buscar optimizar y cuándo no.
En línea

hergue00

Desconectado Desconectado

Mensajes: 22


Ver Perfil
Re: Borrar texto en la consola usando c
« Respuesta #5 en: 2 Mayo 2019, 21:41 pm »

Vale, muchas gracias, me has ayudado bastante!

Una última cosa, como puedo hacer para que si el usuario presiona las teclas ins, supr... no las detecte como caracteres?
En línea

RayR

Desconectado Desconectado

Mensajes: 243


Ver Perfil
Re: Borrar texto en la consola usando c
« Respuesta #6 en: 2 Mayo 2019, 22:37 pm »

Cuando se presiona una tecla "especial", como ins, supr, las flechas, etc., getch lee y retorna dos valores, uno que indica precisamente el hecho de que se presionó una tecla especial, y el siguiente, que devuelve el código de esa tecla. En Turbo C++ el código era 0, pero creo que en Windows es distinto. Puedes agregar un printf que muestre el código leido, justo después de tu primer _getch:

Citar
printf("%d", c);

Al ejecutarlo, presiona la tecla que quieras probar, por ejemplo ins. y verás en pantalla los dos códigos, el primero, que es igual para todas las teclas especiales, y el segundo que es específico de ins, etc. Creo que sólo te interesa el primero, es decir, detectar tecla especial, y simplemente ignorarla (y la siguiente). En ese caso, pones justo después de tus _getch algo como:

Código:
            while (c == <codigo de teclas especiales>) {
                // Quitar del buffer el código de la tecla específica
                _getch();

                // Volver a leer una tecla
                c = _getch();
            }

Sólo se entrará al bucle si se presiona tecla especial, y se sale cuando se presiona una tecla "normal", que te interese procesar.
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines