0

here is my code:

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

int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("Usage: ./vigenere key.\n");
        return 1;
    }

    string keytest = argv[1]; // store argv[1] as string to check if all alphabet
    int key_length = strlen(keytest);

    for (int i = 0, n = strlen(keytest); i < n; i++)
    {
        if (!isalpha(keytest[i]))
        {
            printf("Please use alphabetical key.\n");
            return 1; // return 1 if not alphabet
        }

    }

    int key[key_length];        

    for (int i = 0, n = key_length; i < n; i++) // convert key to all int
    {
        key[i] = toupper(keytest[i]) - 65;  // set all to upper and -65 so that a/A = 0 for key 
    }

    string plain = GetString(); // Get input
    int txtlength = strlen(plain); // Get length of plaintext so don't need to keep calling
    string cipher = plain; // Initialize variable cipher with same length as plaitnex

    for (int i = 0, j = 0, m = txtlength; i < m; i++)
    {
        if (isalpha(plain[i]))        
        {
            if (isupper(plain[i]))
            {
                cipher[i] = ( (plain[i] - 64 + key[j]) % 26) + 64;
                j++;
                if (j == key_length)
                {
                    j = 0;
                }

            }

            if (islower(plain[i]))
            {
                cipher[i] = ( (plain[i] - 96 + key[j]) % 26) + 96;
                j++;
                if (j == key_length)
                {
                    j = 0;
                }

            }
        }

        else if (!isalpha(plain[i])) // store char unchanged if not alphabetical
        {
            cipher[i] = plain[i];
        }

    }
    printf("%s\n", cipher);

}

Comparing my output to the sample output, all my ciphered text EXCEPT for "z" is accurate. What should be ciphered as "z" turns out as ' instead. I think this is due to the cipher formula outputting 26 % 26 as 0 then adding 96 to it. However I am not sure how to fix it, since it seems to be fine for the other letters. I mean I think I separate the formula out and add in an if so that if it = 26, not to % it, but is that the best solution?

I did the latter and used check50 and it was completely fine, but I am thinking there should be a better solution.

0

You have created an unusual "off by 1" problem. Your logic is right, but it is literally off by 1. It also looks like you have a slight misunderstanding of how the logic of applying modulo 26 to loop back to the beginning of the alphabet. It seems right that you should start at 1 for A because of a lifetime of counting things starting at 1, but not here.

The logic of looping back to the beginning with modulo depends on the alphabet being represented by the numbers 0 through 25. Your logic represents letters with the numbers 1 through 27. I'm willing to bet that if you check your code for anything that shifts past z, your results will be off by one letter (or perhaps more if you shift by more than 26).

In your code, you subtract 64 and 96. If you review all of the class material, they subtract 'A' or 'a', in other words, 65 and 97. They also explain in one place that subtracting the letter instead of a number ( int x = ltr - 'A' ) is safer because it eliminates the doubt of what you are doing. Had you done so, you probably wouldn't have had this issue.

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

| improve this answer | |

You must log in to answer this question.

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