0

I've been stuck on vignere.c for quite some time and I can't figure out what is wrong with my code. I received the following errors:

encrypts "world, say hello!" as "xoqmd, rby gflkp!" using "baz" as keyword
    Expecting the following on standard out —  xoqmd, rby gflkp!\n  ... but received the following on standard out instead —  xpsme, tbz ifmmp!
encrypts "BaRFoo" as "CaQGon" using "BaZ" as keyword
    Expecting the following on standard out —  CaQGon\n ... but received the following on standard out instead —  CSGPP
encrypts "BARFOO" as "CAQGON" using "BAZ" as keyword
    Expecting the following on standard out —  CAQGON\n ... but received the following on standard out instead —  CBSGPP

Here is the full check50 output.

I even tried doing my formula with pen and paper and it seems to be checking out but I can't figure out why the output is incorrect.

int main (int argc, string argv[])

{
    if (argc != 2)
    {
        printf("Try again. Please enter a keyword.\n");
        return 1;
    }
    for (int i = 0; i < strlen(argv[1]); i++)

        if (!isalpha(argv[1][i]))
        {
            printf("Try again. Please enter only letters.\n");
            return 1;
        }

    string plaintext;
    plaintext = GetString();
    int j=0;
    string k=argv[1];

    for (int i = 0;i < strlen(plaintext); i++)
    {
        if (j>=strlen(k))
        {
            j = 0;
        }

        if (!isalpha(plaintext[i]))
        {
            printf("%c", plaintext[i]);
        }
        if (isalpha(plaintext[i]))
        {
            if(isupper(plaintext[i]))
            {
                int ciphertext = (plaintext[i]-'A'+(k[j]-'A'))%26+'A';
                printf("%c", ciphertext);
            }
            else if (islower(plaintext[i]))
            {
                int ciphertext = (plaintext[i]-'a'+(k[j]-'a'))%26+'a';
                printf("%c", ciphertext);
            }

            else
            {
                printf("%c", plaintext[i]);
            }
        }
    }
    printf("\n");
    return 0;
}
1
  • Why are you assuming that both the i-th char of the key and the plaintext is simultaneously uppercase or lowercase? The key doesn't need to relate to the plaintext regarding its case.
    – rigel
    Commented Nov 21, 2014 at 7:38

1 Answer 1

1

Let's study what your algorithm does when encrypting BaRFoo with the keyword BaZ.

i = 0, less than the freshly evaluated length of plaintext // true
    j = 0, less than the freshly evaluated length of k // true
    B !isalpha // false
    B isalpha // true
        B isupper // true
            int ciphertext = (B - A + (B - A))%26 + A // results in 67 'C'
            print C

i = 1, less than the freshly evaluated length of plaintext // true
    j = 0, less than the freshly evaluated length of k // true
    a !isalpha // false
    a isalpha // true
        a isupper // false
        a islower // true
            int ciphertext = (a - a + (B - a))%26 + a // results in 92 '/'
            print /

i = 2, less than the freshly evaluated length of plaintext // true
    j = 0, less than the freshly evaluated length of k // true
    R !isalpha // false
    R isalpha // true
        R isupper // true
            int ciphertext = (R - A + (B - A))%26 + A // results in 83 'S'
            print S

i = 3, less than the freshly evaluated length of plaintext // true
    j = 0, less than the freshly evaluated length of k // true
    F !isalpha // false
    F isalpha // true
        F isupper / true
            int ciphertext = (F - A + (B - A))%26 + A // results in 71 'G'
            print G

i = 4, less than the freshly evaluated length of plaintext // true
    j = 0, less than the freshly evaluated length of k // true
    o !isalpha // false
    o isalpha // true
        o isupper // false
        o islower // true
            int ciphertext = (o - a + (B - a))%26 + a // results in 80 'P'
            print P

i = 5, less than the freshly evaluated length of plaintext // true
    j = 0, less than the freshly evaluated length of k // true
    o !isalpha // false
    o isalpha // true
        o isupper // false
        o islower // true
            int ciphertext = (o - a + (B - a))%26 + a // results in 80 'P'
            print P

i = 6, less than the freshly evaluated length of plaintext // false
print newline
exit

As Rigel stated in a comment, the case of the original message should have no bearing on the case of the key.

Also, remember to evaluate your code as you write it. Code smells will alert you to potential issues early and save time overall.

Items that immediately pop out with this review approach:

  • Do you expect the length of either the message or the key to change?
  • You've allowed for the possibility of j changing in value but who do you expect to change it?
  • The code to convert from a character to an integer and produce ciphertext is almost identical and appears in multiple places.

You must log in to answer this question.

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