0

My caesar code has been working perfectly (passed the check50) until I tried to decrypt an 8-character message and discovered that for this number of characters I get a B printed at the end of my cipher text. I tried debugging and it seems that the program loops through my letters correctly (works fine if I just print every character to the screen separately) and only at the very final stage as I try to print the whole string the B is added. I would like to know the reason for this error - what happens for this particular string length that causes this to occur?

I'm still a very beginner so I appreciate any help.

Here's my code:

//Function accepts exactly one command-line argument
int main(int argc, string argv[])
{
    if (argc == 2)
    {
    int k = atoi(argv[1]); //Convert to integer

    if (k > 26) //Wrap around the alphabet (only letters)
    {
        k = k % 26;
    }

    //Prompt user for text
    printf("plaintext: ");
    string plain_text = get_string();


    //Convert into cipher
    int length = strlen(plain_text);

    char cipher_text[length];

    for (int i = 0; i < length; i++)
    {
        //If lower case
        int wrap;

        if (plain_text[i] >= 97 && plain_text[i] <= 122)
        {
            wrap = 122 - plain_text[i]; //amount before z

            if (k > wrap) //To wrap back to a
            {
                cipher_text[i] = 96 + (k - wrap);
            }

            else if (k <= wrap)
            {
                cipher_text[i] = plain_text[i] + k;
            }
        }
        //If upper case
        else if (plain_text[i] >= 65 && plain_text[i] <= 90)
        {
            wrap = 90 - plain_text[i]; //amount before Z

            if (k > wrap)//To wrap back to A
            {
                cipher_text[i] = 64 + (k - wrap);
            }

            else if (k <= wrap)
            {
                cipher_text[i] = plain_text[i] + k;
            }
        }

        //Leave non-alphabetical characters unchanged
        else
        {
            cipher_text[i] = plain_text[i];
        }

        printf("%c", cipher_text[i]); //Print individual characters to check
    }

    //Print the converted text
    printf("\n");
    printf("ciphertext: %s\n", cipher_text);
    return 0;
}

//If no or too many command-line arguments, print error message and return 1
    else
    {
        printf("Please use exactly one command-line argument.\n");
        return 1;
    }
}

Here's an example of the output I get:

~/workspace/pset2/caesar/ $ ./caesar 1
plaintext: H Knud T
I Love U
ciphertext: I Love UB

1 Answer 1

0

You could try

char cipher_text[length + 1]; // +1 for the null terminator
cipher_text[length] = '\0';

BTW, the code is hard to understand, I'm surprised it actually works that far. I'm not sure it always produces right result for multiples of 26 (0, 26, 52, ...). You could try that with a string like ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz, that one should be the same after shifting by 0, 26, ...

3
  • Thank you for your answer. Would you be able to explain why this error occurs though? There are probably other lengths of strings that I'd see a similar problem for, but I haven't found any yet. As I said I haven't observed any problems when I print individual characters, only when I print the whole string and only with 8 characters. I would simply like to understand why this happens. I've tested your string and it works fine - it may not be clear because I didn't use isupper/islower - I was trying to achieve something similar by just using the ASCII code and see if it works. Sorry about that.
    – Tusienka
    Feb 22, 2018 at 7:13
  • I expect any multiple of 8 characters could cause those problems. printf reads the string until it hits a zero byte (which is the C way of how a string is defined). The compiler adds unused bytes to align variables to addresses divisible by 8, so if you have 8 characters (and no zero terminator), the 9th is part of the next variable. For another length, it would hit an unused byte, which initially is likely to be zero (but no guarantee on that). So it accidentally works for lengths not divisible by 8, although without guarantees.
    – Blauelf
    Feb 22, 2018 at 9:16
  • Thank you, it makes more sense now. I have tried your suggestion and works perfectly.
    – Tusienka
    Feb 25, 2018 at 19:15

You must log in to answer this question.

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