0

My vigenere code is compiling and executing; however, despite the wrap-around functionality working, whatever I type seems to shift an extra 13 letters to the right:

Plaintext: ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz
Ciphertext: NOPQRSTUVWXYZABCDEFGHIJKLM nopqrstuvwxyzabcdefghijklm

Using 'e' (ascii value 101) as example plaintext with a cipher of 'A' (so, 0), the function should execute:

     if (islower(plaintext[c]))
            {
                int f = plaintext[c] - 'a';
                plaintext[c] = ((f + input[e]) % 26) + 'a';
            }

     if (islower(plaintext[c]))
            {
                int f = 101 - 97;
                plaintext[c] = ((4 + 0) % 26) + 97;
            }

which should equal 4 + 97, or 101, returning 'e' again, yet doesn't. I've tried the debugger a few times, and haven't been able to come up with a reason why this is happening.

Many thanks in advance for help!

Full code:

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

int main (int argc, string argv[])
{
if (argc < 2 || argc > 2)
{
    printf("Invalid input. Usage: './vigenere k'\n");
    return 0;
}
else
{
    string input = argv[1];
    int h = strlen(input);

    for (int a = 0, b = strlen(input); a < b; a++)
    {
        if (isalpha(input[a]))
        {
            continue;
        }
        else
        {
            printf("Your key must consist of only letters\n");
            return 0;
        }
    }

    string plaintext = get_string("Plaintext: ");
    printf("Ciphertext: ");

for (int d = strlen(plaintext), c = 0; c < d; c++)
    {
        int e = (c % h);

        if (isalpha(plaintext[c]))
        {
            if (islower(plaintext[c]))
            {
                int f = plaintext[c] - 'a';
                plaintext[c] = ((f + input[e]) % 26) + 'a';
            }
            else
            {
                int g = plaintext[c] - 'A';
                plaintext[c] = ((g + input[e]) % 26) + 'A';
            }

            printf("%c", plaintext[c]);
        }
        else
        {
            printf("%c", plaintext[c]);
        }
    }
    printf("\n");
  }
}

1 Answer 1

1

In this code, you see how you subtracted 'a' from the plaintext?

            int f = plaintext[c] - 'a';
            plaintext[c] = ((f + input[e]) % 26) + 'a';

input[e] still contains an ASCII value. Want to guess what impact that has?

Next, you've tied the index for the key directly to the password. What happens when non-alphas are processed? The key index will still advance even though it shouldn't.

What happens for upper vs lower case key?

On a side note, there's a lot of opportunity to simplify the code. In no particular order....

The first else clause isn't needed. Should the if clause execute, the program terminates. Otherwise, the subsequent code will always execute.

The entire if (isalpha(input[a]))... can be simplified by reversing the logic to this:

    if (!isalpha(input[a]))
    {
        printf("Your key must consist of only letters\n");
        return 0;
    }

Also, the standard practice of returning 0 from a program indicates that the program completed successfully. Returning a non-zero is the standard for a unexpected or error termination.

Since you're going to print the char no matter what, is there a way to eliminate one of the printf statements?

Anytime the same exact statement or code block appears more than once, it's an indicator to look for ways to make the code more efficient. ;-)

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

1
  • Thank you!! I finally see my mistake!
    – Matt
    May 5, 2018 at 0:27

You must log in to answer this question.

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