1

I have test many cases and most of them are fine except the following one:

~/workspace/pset2/caesar/ $ ./caesar 2
plaintext: I love tea
ciphertext: K nqxg vgcB

Where does the extra letter "B" come from? And how to fix it? Thanks!

Here is my code:

#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

int ASCII_TO_ALPHABETICAL_UPPER = -65;
int ASCII_TO_ALPHABETICAL_LOWER = -97;

char shift_letter(char letter, int shift);

int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("Please enter an integer for the key.");
        return 1;
    }
    // turn key into integer
    int shift = atoi(argv[1]);

    // get plaintext from user
    printf("plaintext: ");
    string plaintext = get_string();

    // initiate ciphertext;
    char ciphertext[strlen(plaintext) + 1];

    for (int i = 0, n = strlen(plaintext); i < n; i++)
    {
        char letter = plaintext[i];
        if (isalpha(letter))
        {
            // shift letter 
            ciphertext[i] = shift_letter(letter, shift);
        }
        else
        {
            // not a letter, add to cyphertext directly
            ciphertext[i] = letter;
        }
    }

    // print cyphertext
    printf("ciphertext: %s\n", ciphertext);
    return 0;
}

char shift_letter(char letter, int shift)
{
    if (isupper(letter))
    {
        // shift the uppercase letter

        // convert ASCII to alphabetical index
        int alphabetical_index = (int) letter + ASCII_TO_ALPHABETICAL_UPPER;
        // get the shifted alphabetical index
        int shifted_index = (alphabetical_index + shift) % 26;
        // convert back to ASCII
        int ascii_shifted_index = shifted_index - ASCII_TO_ALPHABETICAL_UPPER;
        // return the shifted letter
        return (char) ascii_shifted_index;
    }
    else
    {
        // shift the lowercase letter
        int alphabetical_index = (int) letter + ASCII_TO_ALPHABETICAL_LOWER;
        int shifted_index = (alphabetical_index + shift) % 26;
        int ascii_shifted_index = shifted_index - ASCII_TO_ALPHABETICAL_LOWER;
        return (char) ascii_shifted_index;
    }

}
7
  • Is it the same letter at the end everytime? It seems to me you declare char ciphertext with one more spot than is needed: after all, it needs the same amount of characters as plaintext, doesn't it? If the last letter is different everytime, it could be that it's just 0's and 1's stuck in your char[] that aren't overwritten because you never get to the (n+1)nth element of ciphertext. Let me know if removing the '+1' from ciphertext[strlen(plaintext)+1] works! Mar 7 '17 at 8:42
  • No, delete '+1' doesn't work here.
    – Han Tang
    Mar 7 '17 at 8:56
  • I use '+1' because according to the lecture, at the end of a string there is an implicit "\0" to determine the end of a string.
    – Han Tang
    Mar 7 '17 at 9:00
  • In that sense: shouldn't you loop through your plaintext up to strlen(plaintext) +1 as well, as to copy the implicit '\0' as well? Mar 7 '17 at 9:34
  • Also, somehow it looks odd that you don't initialize n as an int in the for loop. Did you never get an error for that? Anyways, that's besides the point because it seems to work haha Mar 7 '17 at 9:35
1

Currently it looks like you're looping through your ciphertext from 0 up to strlen(plaintext), however, you assigned ciphertext the size of strlen(plaintext)+1.

Here's what's happening: The GetString() function gets a string from the user and, recalling what you might have seen in the lectures, every string is simply an array of characters ending with '\0' to mark the end of the string. You yourself are making ciphertext an array of characters, but it won't be a correctly formatted string until it ends with the same null character '\0'.

A simple fix would be looping, instead up to n, up to n+1: Making sure you ALSO copy the plaintext's null character!

Hope that helps and explains it more, if not, feel free to ask!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .