My substitution cipher is producing the correct output on my terminal when I run the same checks. I have reviewed other responses to similar issues but wasn't able to figure out how to find my error. Any help you can provide is much appreciated.
When I run Check50 it produces the following output:
Results for cs50/problems/2020/x/substitution generated by check50 v3.1.2 :) substitution.c exists :) substitution.c compiles :( encrypts "A" as "Z" using ZYXWVUTSRQPONMLKJIHGFEDCBA as key output not valid ASCII text :( encrypts "a" as "z" using ZYXWVUTSRQPONMLKJIHGFEDCBA as key output not valid ASCII text :( encrypts "ABC" as "NJQ" using NJQSUYBRXMOPFTHZVAWCGILKED as key output not valid ASCII text :( encrypts "XyZ" as "KeD" using NJQSUYBRXMOPFTHZVAWCGILKED as key output not valid ASCII text :) encrypts "This is CS50" as "Cbah ah KH50" using YUKFRNLBAVMWZTEOGXHCIPJSQD as key :) encrypts "This is CS50" as "Cbah ah KH50" using yukfrnlbavmwzteogxhcipjsqd as key :) encrypts "This is CS50" as "Cbah ah KH50" using YUKFRNLBAVMWZteogxhcipjsqd as key :) encrypts all alphabetic characters using DWUSXNPQKEGCZFJBTLYROHIAVM as key :) handles lack of key :) handles invalid key length :) handles invalid characters in key :) handles duplicate characters in key :) handles multiple duplicate characters in key
My code:
#include <ctype.h>
#include <stdio.h>
#include <math.h>
#include <cs50.h>
#include <string.h>
#include <stdlib.h>
//Class Variables
// string of 26 alpha characters will be passed in the command to run the program as an argument sent to the main method parameter argv[]. Used to construct the cipher alphabet
string key;
// plaintext alphabet is a constant in all caps only. Only alpha characters are considered.
char ALPHABET[26] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
// ciphertext alphabet is initialized to the same values as ALPHABET to allocate memory. It is shifted the amount of positions indicated in the command line argument (key).
char cipher_alphabet[26] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
// used to store the user input of the original message
string plaintext;
//used to store the changes to plaintext when it is shifted by the amount of characters indicated in the key.
string ciphertext;
//Class Methods
// sets the cipher alphabet using key
void setCipherAlphabet(void);
// encrypts plaintext by shifting it key positions
void encrypt(void);
// TODO not implemented yet
void decrypt(string ciphertext);
// prints all class variables to aid in debugging.
void print_vars(void);
// used by the encrypt method to find the corespoonding character in the cipher alphabet
char getCipherChar(char c);
// is used to determine if the command line argument passed running the program contains only alpha characters. returns true if str has all alpha characters; false otherwise.
bool is_all_alpha(string str);
// returns true if str contains a duplicate character; false otherwise.
bool hasDuplicate(string str);
int main(int argc, string argv[])
{
// validating command prompt argument and getting plaintext input.
//if a valid argument was passed in the command line prompt
if (argc == 2 && is_all_alpha(argv[1]) && strlen(argv[1]) == 26 && !hasDuplicate(argv[1]))
{
key = argv[1];
// get user input for the plaintext message
plaintext = get_string("plaintext: ");
while (strlen(plaintext) < 1)
{
plaintext = get_string("plaintext: ");
}
}
//if no arguments or too many arguments were passed on command line
else if (argc == 1 || argc > 2)
{
printf("Usage: ./substitution key\n");
return 1;
}
//handles duplicate characters in key
else if (hasDuplicate(argv[1]))
{
printf("Key must contain 26 unique alpha characters. \n");
return 1;
}
// if another type of invalid key was passed through the command line exit program
else
{
printf("Key must contain 26 characters.\n");
return 1;
}
// initialize the cipher alphabet
setCipherAlphabet();
// initialize ciphertext to allocate memmory
int size = strlen(plaintext);
// create a string of spaces to allocate memory for ciphertext
char str[size];
for (int i = 0; i < size; i++)
{
str[i] = plaintext[i];
}
ciphertext = str;
//encrypt the plaintext message.
encrypt();
//print the encrypted message to the command prompt.
printf("ciphertext: ");
printf("%s", ciphertext);
printf("\n");
//exit program
return 0;
}// end main
bool is_all_alpha(string str)
{
for (int i = 0; i < strlen(str); i++)
{
if (!isalpha(str[i]))
{
return false;
}
}
return true;
}
//initializes the cipher alphabet given the key as an input.
void setCipherAlphabet(void)
{
for (int i = 0; i < 26; i++)
{
cipher_alphabet[i] = toupper(key[i]);
}
}
void print_vars(void)
{
printf("Key: ");
printf("%s", key);
printf("\n");
printf("Cipher Alphabet: ");
printf("%s", cipher_alphabet);
printf("\n");
printf("plaintext: ");
printf("%s", plaintext);
printf("\n");
printf("ciphertext: ");
printf("%s", ciphertext);
printf("\n");
}
void encrypt(void)
{
for (int i = 0; i < strlen(plaintext); i++)
{
for (int j = 0; j < 26; j++)
{
if (toupper(plaintext[i]) == toupper(ALPHABET[j]))
{
ciphertext[i] = cipher_alphabet[j];
}
}
if (islower(plaintext[i]))
{
ciphertext[i] = tolower(ciphertext[i]);
}
}
}
// returns true if str contains a duplicate character; false otherwise.
bool hasDuplicate(string str)
{
for (int i = 0; i < strlen(str); i++)
{
for (int j = i + 1; j < strlen(str); j++)
{
if (str[i] == str[j])
{
return true;
}
}
}
return false;
}