Search code examples
cif-statementcs50vigenere

CS50 PSet 2 - Vigenere - Making sure keyword is alphabetical


I'm currently working on the Vigenere cipher in CS50 using the language C. The requirement is to make a program which enciphers some plaintext based on a keyword (both of which the user inputs). It will encipher based on the Vigenere cipher. I'm finding it hard to describe in words what the Vigenere cipher is so here is an example from the CS50 specification:

If Vigenère himself wanted to say HELLO to someone confidentially, using a keyword of, say, ABC, he would encrypt the H with a key of 0 (i.e., A), the E with a key of 1 (i.e., B), and the first L with a key of 2 (i.e., C), at which point he’d be out of letters in the keyword, and so he’d reuse (part of) it to encrypt the second L with a key of 0 (i.e., A) again, and the O with a key of 1 (i.e., B) again. And so he’d write HELLO as HFNLP.

The keyword has to be a string of all alphabetical letters and must be given as the second command-line argument, i.e. argv[1] in my code below. The problem I'm having is that I can't get the program to reject the key if it isn't alphabetical and to continue if it is all alphabetical. I have tried doing it like this (see code below) and it's not returning the printf error message if I include a number in argv[1]. Please can someone offer some advice on what is wrong? Apologies if the format isn't great..

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

// declare command line argument variables
int main(int argc, string argv[])
{

string k = argv[1];

//return error if there aren't two command line arguments
if (argc != 2)
    {
        printf("Usage: ./vigenere k\n");
        return 1;
    }

//make sure key is all alphabetical
for (int i = 0; i < strlen(k); i++)

 {
    if(isalpha(k[i]))
    {
    return 0;
    }

    else
    {
    return 1;
    printf("Please ensure all characters are alphabetical.\n");
    }
 }
}

I also tried it like this instead of what is inside the for loop above and it didn't work:

if(!isalpha(k[i]))
    {
    return 1;
    printf("Please ensure all characters are alphabetical.\n");
    }

Solution

  •    if(isalpha(k[i]))
        {
        return 0;
        }
    

    exits the program as soon as there's an alphabet in argv[1]. Instead you want to continue the loop until all the characters are checked. So, do:

     for (size_t i = 0; i < strlen(k); i++)
     {
        if(!isalpha(k[i]))
        {
        printf("Please ensure all characters are alphabetical.\n");
        return 1;
        }
     }
    

    You also need to put the argument checking before you use argv[1].

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