I've been stuck for so many hours on this, and need some advice :(
When I loop through the plaintext input, if the character contains a 'z' character then it outputs a '{' character. I've tried printing out the integer values, and it shows that 25 is being shifted but it seems that the loop is actually shifting by 27 characters. These are my error messages:
:( encrypts "barfoo" as "caqgon" using "baz" as keyword expected "ciphertext: ca...", not "ciphertext: ca..."
$ ./vigenere baz
plaintext: barfoo
ciphertext: casgop
It seems to go wrong only on the 3rd character each time.
Thanks in advance for any insight :)
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int shift(char c);
int main(int argc, string argv[])
{
// end the program if more than 1 argument is provided
if (argc != 2)
{
printf("Usage: You must enter a single keyword\n");
return 1;
}
// iterate over each character in the keyword
for (int i = 0; i < strlen(argv[1]); i++)
{
//return and exit the program if it contains any digits
if (isdigit(argv[1][i]))
{
printf("Usage: The keyword must consist of only alphabetical characters\n");
return 1;
}
}
// prompt user for a string to be ciphered
string plain = get_string("plaintext: ");
printf("ciphertext: ");
// define the length of the keyword so we know when to reset it to 0
int keyword_length = strlen(argv[1]);
// store length of the plaintext string in a variable for iteration
int plen = strlen(plain);
// iterate over the plaintext, and the keyword
for (int j = 0, k = 0; j < plen; j++)
{
if (isalpha(plain[j]) && (plain[j] != '\0' && plain[j] != '\n'))
{
// once iterated through to the end of the keyword, wrap the loop back to the beginning of the keyword
if ((k == keyword_length) && (keyword_length != '\0'))
{
k = 0;
}
// convert the kth character of keyword into an integer one character per loop iteration
int keyword = shift(argv[1][k]);
// apply modulo of keyword length to the index of the key, increment the keyword counter only if an alphabetic
// character is found
if (isupper(plain[j]))
{
printf("%c", (plain[j] + (keyword % keyword_length)));
k++;
}
else if (islower(plain[j]))
{
printf("%c", (plain[j] + (keyword % keyword_length)));
k++;
}
}
else
{
// print out any non alphabetic characters as they are
printf("%c", plain[j]);
}
}
printf("\n");
return 0;
}
int shift(char c)
{
// define an int variable
int i;
// convert char c to ascii if uppercase
if (isupper(c))
{
i = ((c - 65) % 26);
}
// convert char c to ascii if lowercase
if (islower(c))
{
i = ((c - 97) % 26);
}
return i;
}