-1

I have an assignment in which we're to make a Caesar (rot) cipher, but without using array notation (a[b]). It seems like it should work, but it spews out random garbage past the end of the string, even though a check is performed on lines 41 and 51

/* lab 08 */
/* exercise for loops and pointers */
/* assume that plain text which needs to be encrypted has
 * only capital letters */

#include <stdio.h>
#include <stdlib.h>


int Caesar_encrypt(char *p, char *s, int enckey);
int Caesar_decrypt(char *p, char *s, int enckey);

int main(void){
    char A[]="THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG";
    char B[50], /* stores encrypted output string   */
    C[50];  /* stores decrypted output using string B as source */
    int enckey,
    statuse, statusd; /* they store return values from the functions */

    printf("Plaintext for encryption is : %s \n", A);

    printf("Input numerical key for Caesar's cypher : ");
    scanf("%d", &enckey );  // COMPLETE THIS

    putchar('\n');
    printf("You entered encryption key %d \n", enckey);
    /* encrypt by Caesar's cypher */
    statuse= Caesar_encrypt(A, B, enckey);

    printf("Ciphertext is : %s \n", B);

    /* decrypt by Caesar's cypher */
    statusd = Caesar_decrypt(B, C, enckey);
    printf("Decrypted text is: %s \n", C);
    exit (0);
}

int Caesar_encrypt(char *p, char *s, int enckey) {  // COMPLETE THE INPUT PARAMETERS
    enckey %= 26;
    int i;
    for (i = 0; *(p+i); i++) {
        if (*(p+i) != ' ') *(s+i) = (*(p+i) - 'A' + enckey) % 26 + 'A';
        else *(s+i) = ' ';
    }
    return 0;
}

int Caesar_decrypt(char *p, char *s, int enckey) {  // COMPLETE THE INPUT PARAMETERS
    enckey %= 26;
    int i;
    for (i = 0; *(p+i); i++) {
        if (*(p+i) != ' ') *(s+i) = (*(p+i) - 'A' + 26 - enckey) % 26 + 'A';
        else  *(s+i) = ' ';
    }
    return 0;
}

Sample output:

Plaintext for encryption is : THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG 
Input numerical key for Caesar's cypher : 1

You entered encryption key 1 
Ciphertext is : UIF RVJDL CSPXO GPY KVNQT PWFS UIF MBAZ EPH8???THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG 
Decrypted text is: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG47;Q9=@SGD PTHBJ AQNVM ENW ITLOR NUDQ SGD KZYX CNF8???THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG 
lurker
  • 56,987
  • 9
  • 69
  • 103
  • 2
    Your `Caesar_decrypt` and `Caesar_encrypt` functions don't zero-terminate the string when they're done. So `printf` doesn't know where to stop printing it. – lurker Mar 18 '14 at 17:28
  • relevant: http://favo.s3.amazonaws.com/if-programming-languages-were-essays.jpg –  Mar 18 '14 at 17:59
  • have you tried debugging the code..........if you had then i think you would have known to terminate the string. – wrangler Aug 13 '17 at 01:38

3 Answers3

3

You're not zero-terminating the result strings in the encrypt or decrypt functions.

You need to add *(p+i) = 0; or, preferably, p[i] = 0; after the loop in the encrypt function, and s[i] = 0; after the loop in the decrypt function.

John Bode
  • 119,563
  • 19
  • 122
  • 198
2

I believe the problem is that your encrypt/decrypt functions do stop encrypting/decpryting when they encounter zero in the source array (which is correct), but they don't explicitly zero-terminate the target array (which is a problem). Try adding an explicit null termination after the loops.

Theodoros Chatzigiannakis
  • 28,773
  • 8
  • 68
  • 104
2

You need to proper terminate the strings in both your Caesar_encrypt() and Caesar_decrpyt() functions.
C strings are terminated with a single '\0' character, so you can add this line before the return 0; at the bottom of the aforementioned function bodies:

    .... 

    // Terminate the string, adding a \0
    *(s+i) = '\0';

    return 0;
}

BTW: I prefer using the array syntax s[i] to identify single characters in strings, so I'd do s[i] = 0;.


Moreover, you may want to use const to mark the input (read-only) strings in your function signatures (and update function definitions as well):

int Caesar_encrypt(const char *p, char *s, int enckey);
int Caesar_decrypt(const char *p, char *s, int enckey);
Mr.C64
  • 41,637
  • 14
  • 86
  • 162
  • I don't like it either, but our function prototypes and most other (garage, quite frankly) code is given by the TA –  Mar 18 '14 at 17:57