I wrote a program for a problem in Harvard's CS50 course, Vigenere (week 2).
Here is a description of what the program needs to do:
Design and implement a program that encrypts messages using Vigenère’s cipher.
Implement your program in a file called
vigenere.c
in a directory calledvigenere
.Your program must accept a single command-line argument: a keyword, k, composed entirely of alphabetical characters.
If your program is executed without any command-line arguments, with more than one command-line argument, or with one command-line argument that contains any non-alphabetical character, your program should print an error (of your choice) and exit immediately, with
main
returning1
(thereby signifying an error).Otherwise, your program must proceed to prompt the user for a string of plaintext, p, (as by a prompt for
plaintext:
) which it must then encrypt according to Vigenère’s cipher with k, ultimately printing the result (prepended withciphertext:
and ending with a newline) and exiting, withmain
returning0
.With respect to the characters in k, you must treat
A
anda
as 0,B
andb
as 1, …, andZ
andz
as 25.Your program must only apply Vigenère’s cipher to a character in p if that character is a letter. All other characters (numbers, symbols, spaces, punctuation marks, etc.) must be outputted unchanged. Moreover, if your code is about to apply the jth character of k to the ith character of p, but the latter proves to be a non-alphabetical character, you must wait to apply that jth character of k to the next alphabetical character in p; you must not yet advance to the next character in k.
Your program must preserve the case of each letter in p.
I received full credit for my answer, but I still want to clean up the code if possible. I am new to programming, so I enjoy seeing what changes more experienced programmers would make.
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int check(string argv);
int shift(char c);
int main(int argc, string argv[])
{
//check for valid key and save
int valid = 0;
if (argc == 2)
{
valid = check(argv[1]);
}
else
{
printf("Usage: ./vigenere keyword\n");
return 1;
}
//begin encryption
int key;
int index = -1;
int new_code;
if (valid == 1)
{
//get plaintext to encrypt
string plaintext = get_string("plaintext: ");
printf("ciphertext: ");
//iterate through each char of plaintext
for (int j = 0, l = strlen(plaintext); j < l; j++)
{
if (isalpha(plaintext[j]))
{
//iterate through the keyword only when there is an alpha in the plaintext
index++;
key = shift(tolower(argv[1][index % strlen(argv[1])]));
new_code = (int) plaintext[j] + key;
if ((int) tolower(plaintext[j]) + key > 122)
{
new_code = new_code - 26;
printf("%c", (char) new_code);
}
else
{
printf("%c", (char) new_code);
}
}
else
{
printf("%c", (char) plaintext[j]);
}
}
printf("\n");
}
else
{
printf("Usage: ./vigenere keyword\n");
return 1;
}
}
//create key
int shift(char c)
{
int key = (int) c - 97;
return key;
}
//decide if key is valid
int check (string argv)
{
int val = 0;
for (int i = 0, n = strlen(argv); i < n; i++)
{
if (isalpha(argv[i]))
{
val = 1;
}
else
{
val = 0;
break;
}
}
return val;
}