0

The code doesn't encrypt the nonalpha characters, so that is good, but it continues the count through the keyword rather than pausing it. So I encounter this problem:

Expected: ./vigenere baz plaintext: hello, world! ciphertext: iekmo, vprke!

Actual: ./vigenere baz plaintext: hello, world! ciphertext: iekmo, wnslc!

I am brand new to computer science, so I'm sure I'm missing something obvious. Here is my code:

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

int shift(char c);

string keyword; 

int key;

int main(int argc, string argv[])
{
    // check for single command-line argument
    if (argc == 2) 
    {
        // isolate key
        keyword = argv[1];
        // iterate through key to verify that each character is a digit
        int keys[strlen(keyword)];
        for (int i = 0, n = strlen(keyword); i < n; i++)
        {
            if (! isalpha(keyword[i]))        
            {
                printf("Usage: %s keyword\n", argv[0]);
                return 1;
            }
            else
            {
                key = shift(keyword[i]);
                keys[i] = key;
            }
        } 
        // get plaintext from user
        string s = get_string("plaintext: ");
        printf("ciphertext: ");
        // iterate over each character of plaintext
        for (int i = 0, n = strlen(s); i < n; i++)
        {
            // if uppercase, rotate, preserve case, and print out new character
            if (isupper(s[i]))
            {

                printf("%c", (((s[i] - 65) + keys[i % strlen(keyword)]) % 26) + 65);
            }
            else
                // if lowercase, rotate, preserve case, and print out new character
                if (islower(s[i]))
                {
                    printf("%c", (((s[i] - 97) + keys[i % strlen(keyword)]) % 26) + 97);
                }
            // if character, print out as is
                else
                {
                    printf("%c", s[i]);
                }
        }
        printf("\n");
        return 0;
    }    
    else
    {
        printf("Usage: %s keyword\n", argv[0]);
        return 1;
    }
}
int shift(char c)
{
    int k;
    //if uppercase
    if (isupper(c))
    {
        k = (((int) c) - 65);
    }
    //if lowercase
    else
    {
        k = (((int) c) - 97);
    }
    return k;
}
3
  • 1
    Does this answer your question? Key looping in Vigenere Jan 16 '20 at 12:40
  • After reading it, I'm getting that I should use a separate counter, but I'm still not understanding how to do that. I'm guessing it has something to do with recursion? Jan 17 '20 at 16:58
  • No, not recursion. Another variable, that you control within the loop. Add 1 when it's used and make sure it doesn't get "bigger" than the length of the keyword. The plaintext and the key are consumed at different rates, so they should be controlled (indexed) by different variables. And FYI vigenere has been retired in the 2020 version of the edx course. Jan 18 '20 at 11:31

You must log in to answer this question.

Browse other questions tagged .