0

I've gotten stuck on Vigenere trying to shift the keyword only on letters. I've tried several different tactics; a for loop around the letters ending before the not letters, ifs, placing them in different locations inside and out of the cipher for loop, etc. I've also scoured a dozen different websites looking for clues as to how and why. Yes, I've studied other code I've found, but I don't understand Why things belong in those places. Can someone help me to understand the what and why of my next steps please?

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

void check(int argv[1]);     //for isdigit
int shift(char c);    //shift function

int main(int argc, string argv[])
{
    //Prompt for input in command-line, only 1
    if (argc != 2)
    {
        printf("Usage: ./vigenere keyword\n");
        return 1;
    }
    //Check for digits
    //Iterate over chars in argv[1]
    for (int j = 0, n = strlen(argv[1]); j < n; j++)
    {     
        //Check for alphas
        if (isalpha(argv[1][j]) == 0)
        {
            printf("Usage: ./vigenere keyword\n");
            return 1;
        }
    }     

    /*    //convert to int
    int k = atoi(argv[1]);        */
    //plaintext to int
    string plaintext = get_string("plaintext: ");
    printf("ciphertext: ");
    for (int i = 0; i < strlen(plaintext); i++)
    {
        if (isalpha(plaintext[i]))
        {
            int key = shift(argv[1][i % strlen(argv[1])]);
            //Lowercase letters
            if (islower(plaintext[i]))
            {
                printf("%c", (((plaintext[i] - 97) + key) % 26) + 97);
            }
            //Uppercase letters
            else if (isupper(plaintext[i]))
            {
                printf("%c", (((plaintext[i] - 65) + key) % 26) + 65);
            }
         }
         //Not a letter
         else
        {
            printf("%c", plaintext[i]);
        }  
    }
    printf("\n");        
}   

int shift(char c)
{
    if (islower(c))
    {
        //to make 0 to 25        
        c = c - 97;  
        return c;
    }
    else if (isupper(c))
    {
        //to make 0 to 25        
        c = c - 65;   
        return c;
    }
    else
    {
        return 1;
     }
    return 0;
}
0

I'll get you started. Your code has a very common mistake. It uses the same index, i, for both the plaintext and the key. The problem is that it can't. The key (argv[1]) can only consume a letter when an alpha is processed and NEVER when a non-alpha is processed from the plaintext. So, the key needs an independent index variable that is only incremented when a letter is encoded from the plaintext and not incremented when a non-letter is processed.

As a side note, look at the last two return statements in your shift() function. It looks to be using return 1 and return 0 as error conditions. But, if the letter passed to shift() is a, the return value is 0. B returns 1. So, that would be a problem if anything goes wrong. Next, there's nothing to handle any kind of error code returned to main. I'd also point out that a return statement in a function never terminates the program. It just returns processing to the calling code.

If this answers your question, please click on the check mark to accept. 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 .