Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: kikian94 en 26 Octubre 2013, 11:18 am



Título: cifrado cesar en c
Publicado por: kikian94 en 26 Octubre 2013, 11:18 am
Hola buenos dias, tengo que hacer un programa que encripte y desencripte una secuencia de caracteres en mayuscula mediante el cifrado cesar, pero no logro que arranque se me queda pillado el programa y no se como resolverlo:

el problema lo tengo en el scanf del do que no entra e imprime directamente el mensaje de salida diciendo que ha habido un error con el caracter introducido

Código
  1. char cifrar(int desplazamiento, char caracter);
  2. char descifrar();
  3.  
  4. int main(void){
  5.  
  6. int respuesta;
  7. char caracter;
  8. int desplazamiento;
  9. char caracterConvertido;
  10.  
  11. printf("¿Desea cifrar o descifrar?\n");
  12. fflush(stdout);
  13. printf("cifrar--> 0\n");
  14. fflush(stdout);
  15. printf("descifrar -->1\n");
  16. fflush(stdout);
  17. scanf("%d",&respuesta);
  18.  
  19. do{
  20. printf("Introduce la clave de cifrado\n");
  21. fflush(stdout);
  22. scanf("%d",&desplazamiento);
  23.  
  24.  
  25. if(desplazamiento<0){
  26. printf("Introduce un valor valido\n");
  27. fflush(stdout);
  28. }
  29. }while(desplazamiento<0);
  30.  
  31. if(respuesta==0){
  32.  
  33. printf("Introduce el texto a cifrar:");
  34. fflush(stdout);
  35.  
  36. do{
  37.  
  38. fflush(stdin);
  39. scanf("%c",&caracter);
  40.  
  41. caracterConvertido = cifrar(desplazamiento,caracter);
  42. printf("%c",caracterConvertido);
  43. fflush(stdout);
  44. if((caracter<='A')||(caracter>='Z')){
  45. printf("Error en los caracteres introducidos");
  46. fflush(stdout);
  47. }
  48. }while(((caracter>='A')&&(caracter<='Z'))||(caracter !='\n'));
  49.  
  50. printf("*** El texto cifrado es (entre flechas): -->");
  51. fflush(stdout);
  52.  
  53. printf("<-- ***\n");
  54. fflush(stdout);
  55.  
  56. printf("Fin del programa");
  57. fflush(stdout);
  58.  
  59. }
  60. if(respuesta==1){
  61. //descifrar();
  62. }
  63. return 0;
  64. }
  65. char cifrar(int desplazamiento, char caracter){
  66.  
  67. char caracterConvertido;
  68.  
  69. caracterConvertido=caracter + desplazamiento;
  70.  
  71. return caracterConvertido;
  72. }
  73.  


Título: Re: cifrado cesar en c
Publicado por: rir3760 en 26 Octubre 2013, 15:14 pm
Problemas con el programa hay varios.

El primero es el uso de fflush(stdin) en el bucle que mencionas, aquí hay dos escenarios:
A) La función no tiene efecto, si eso sucede el primer carácter a procesar sera el avance de linea de (valga la redundancia) la linea anterior (introducción de la clave de cifrado), ese carácter se procesa y causa la salida del bucle.
B) La función tiene efecto, ello resulta en que la linea completa (salvo el primer carácter) que se debe cifrar se pierde.

Lo que debes hacer es eliminar esa llamada a función y en su lugar verificar que el resto de la linea (por lo menos el '\n') al introducir la clave de cifrado se descarte. Opciones y mas información 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).

Otro se encuentra en la validación dentro del bucle:
Código
  1. if ((caracter <= 'A') || (caracter>='Z')){
  2.   printf("Error en los caracteres introducidos");
  3.   fflush(stdout);
  4. }
Con ello se indica que tanto 'A' como 'Z' no son caracteres validos, ahí debes utilizar los operadores '>' y '<'.  También debes eliminar los paréntesis y la llamada a fflush ya que no son necesarios.

El ultimo problema a corregir en el programa es uno de diseño: para poder imprimir el texto cifrado o descifrado en medio del texto "*** El texto cifrado es ..." debes almacenar la linea en un array.

Un saludo


Título: Re: cifrado cesar en c
Publicado por: kikian94 en 26 Octubre 2013, 17:22 pm
se puede realizar sin arrays? se supone que el ejercicio se tiene que hacer sin arrays, habia pensado que se podia realizar


Título: Re: cifrado cesar en c
Publicado por: rir3760 en 26 Octubre 2013, 17:42 pm
se puede realizar sin arrays?
Si (por un momento pensé que se trataba de cifrar/descifrar varias lineas, mea culpa).

Pero, en mi opinión, es mas fácil declarar un array, leer una linea con fgets y después procesarla:
Código
  1. char linea[100];
  2. int i;
  3.  
  4. /* ... */
  5.  
  6. puts("Texto a procesar:");
  7. fgets(linea, 100, stdin);
  8.  
  9. /* ... */
  10.  
  11. /* Procesamos cada uno de los caracteres */
  12. for (i = 0; linea[i] != '\0' && linea[i] != '\n'; i++){
  13.   /* Procesamos el caracter linea[i] */
  14. }

Un saludo


Título: Re: cifrado cesar en c
Publicado por: kikian94 en 26 Octubre 2013, 21:06 pm
lo he estado mirando pero sigo sin ser capaz de que funcione





Código
  1. #include<stdio.h>
  2.  
  3. char cifrar(int desplazamiento, char caracter);
  4. char descifrar(int desplazamiento, char caracter);
  5.  
  6. int main(void){
  7.  
  8. int respuesta;
  9. char caracter;
  10. int desplazamiento;
  11. char caracterConvertido;
  12. char cadena[100];
  13. int i=0;
  14. int j=0;
  15.  
  16. printf("¿Desea cifrar o descifrar?\n");
  17. fflush(stdout);
  18. printf("cifrar--> 0\n");
  19. fflush(stdout);
  20. printf("descifrar -->1\n");
  21. fflush(stdout);
  22. scanf("%d",&respuesta);
  23.  
  24. do{
  25. printf("Introduce la clave de cifrado\n");
  26. fflush(stdout);
  27. scanf("%d",&desplazamiento);
  28.  
  29.  
  30. if(desplazamiento<0){
  31. printf("Introduce un valor valido\n");
  32. fflush(stdout);
  33. }
  34. }while(desplazamiento<0);
  35.  
  36. if(respuesta==0){
  37.  
  38. printf("Introduce el texto a cifrar:");
  39. fflush(stdout);
  40.  
  41. do{
  42.  
  43. if((caracter<'A')||(caracter>'Z')){
  44. printf("Error en los caracteres introducidos\n");
  45. }
  46.  
  47. scanf("%c",&caracter);
  48.  
  49. caracterConvertido = cifrar(desplazamiento,caracter);
  50. cadena[j]= caracterConvertido;
  51. j++;
  52.  
  53.  
  54.  
  55. }while(((caracter>='A')&&(caracter<='Z'))||(caracter !='\n'));
  56.  
  57. printf("*** El texto cifrado es (entre flechas): -->");
  58. fflush(stdout);
  59.  
  60. for(i=0;i<100;i++){
  61. printf("%c", cadena[i]);
  62. }
  63.  
  64. printf("<-- ***\n");
  65. fflush(stdout);
  66.  
  67. printf("Fin del programa");
  68. fflush(stdout);
  69.  
  70. }
  71. if(respuesta==1){
  72. //descifrar();
  73. }
  74. return 0;
  75. }
  76. char cifrar(int desplazamiento, char caracter){
  77.  
  78. char caracterConvertido;
  79.  
  80. caracterConvertido=caracter + desplazamiento;
  81.  
  82. return caracterConvertido;
  83. }
  84.  


Título: Re: cifrado cesar en c
Publicado por: rir3760 en 27 Octubre 2013, 02:24 am
Para que el programa genere la salida esperada se necesitan tres cambios.

1) Eliminar el resto de la linea justo después de pedir el desplazamiento y antes de pedir el texto a cifrar. Esto lo puedes realizar con un bucle:
Código
  1. {
  2.   int ch;
  3.  
  4.   while ((ch = getchar()) != EOF && ch != '\n')
  5.      ;
  6. }

2) Debes cifrar solo los caracteres en mayúsculas. En tu bucle cifras el carácter sin importar cual es y solo entonces verificas si es valido. El bucle se debe cambiar a (se puede acortar mas utilizando las funciones getchar e isupper):
Código
  1. printf("Introduce el texto a cifrar:");
  2. fflush(stdout);
  3.  
  4. while (1){
  5.   scanf("%c", &caracter);
  6.  
  7.   if (caracter >= 'A' && caracter <= 'Z')
  8.      cadena[j++] = cifrar (desplazamiento, caracter);
  9.   else
  10.      break;
  11. }

3) Por ultimo imprimes de forma indiscriminada cien caracteres cuando debes imprimir solo los caracteres introducidos por el usuario (hasta el primer carácter invalido), hay que cambiar ese bucle a:
Código
  1. for (i = 0; i < j; i++)
  2.   printf("%c", cadena[i]);
  3.  

Con las modificaciones el programa funciona correctamente.

Un saludo


Título: Re: cifrado cesar en c
Publicado por: kikian94 en 29 Octubre 2013, 15:01 pm
muchas gracias, ya lo estuve mirando y lo consegui hacer funcionar  :D