caesar.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /* This program outputs a file (or stdin) in a caesar cipher. */
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h> //strtol
  5. #include <stdbool.h>
  6. #include <assert.h>
  7. #include <argp.h>
  8. #define DEFAULT_SHIFT 1
  9. char fileName [128];
  10. short int shift = DEFAULT_SHIFT;
  11. const char * argp_program_version = "0.1";
  12. const char * argp_program_bug_address = "jbranso@dismail.com";
  13. error_t argp_err_exit_status;
  14. static const struct argp_option options [] =
  15. {
  16. {"file" , 'f', "FILE", 0, "Output the caesar cipher of a file." },
  17. {"shift", 's', "INT", 0, "Specify the shift of the cipher." },
  18. { 0 }
  19. };
  20. //define an argp parse function
  21. error_t argp_parser (int opt, char *arg, struct argp_state *state)
  22. {
  23. extern char fileName [];
  24. extern short int shift;
  25. switch (opt)
  26. {
  27. // if this parser function is called on an option that it doesn't recognize, then don't do anything.
  28. default:
  29. return ARGP_ERR_UNKNOWN;
  30. case 'f':
  31. {
  32. memcpy (fileName, arg, strlen (arg));
  33. break;
  34. }
  35. case 's':
  36. {
  37. shift = abs ((int) strtol (arg, NULL, 0));
  38. if (shift >= 26)
  39. shift = shift % 26;
  40. break;
  41. }
  42. }
  43. return 0;
  44. }
  45. /* a string containing the basic usage of this program. */
  46. struct argp argp =
  47. {
  48. options, argp_parser, 0,
  49. "A simple program implementing a caesar cipher.\nThe default shift is 1."
  50. };
  51. /* This function decrypts letters.
  52. print_shift('a', 1) -> 'b'
  53. print_shift('B', 1) -> 'C'
  54. */
  55. void print_shifted (int shift, int c)
  56. {
  57. unsigned int lower, upper; // upper is 'a' or 'A', and lower is 'z' or 'Z'
  58. if (isupper (c))
  59. {
  60. lower = 'A';
  61. upper = 'Z';
  62. }
  63. else
  64. {
  65. lower = 'a';
  66. upper = 'z';
  67. }
  68. // if we add the shift, and the resulting char is not a letter, then
  69. // we need to do tweak things.
  70. c += shift;
  71. if ( abs (c) > upper)
  72. c = lower + (c - (upper + 1));
  73. putchar (c);
  74. }
  75. void encrypt (int shift, FILE * stream)
  76. {
  77. int c; /* If I make this a char c, then 'z' + 7 = -128 */
  78. while ((c = getc(stream)) != EOF)
  79. {
  80. //if the char is a number or punctionation, etc, print it.
  81. if (!(isalpha ((int) c)))
  82. putchar(c);
  83. else
  84. print_shifted(shift, c);
  85. }
  86. }
  87. int main (int argc, char **argv) {
  88. extern char fileName [];
  89. extern short int shift;
  90. argp_parse (&argp, argc, argv, 0, 0, 0);
  91. FILE * stream;
  92. if ((stream = fopen (fileName, "r")) == NULL)
  93. stream = stdin;
  94. encrypt (shift, stream);
  95. fclose (stream);
  96. return 0;
  97. }