After finishing most of the program, for some reason when check50 attempts to encrypt BaRFoo using keyword BaZ as well as the other attempts for the variations of barfoo and "hello, world", my code doesn't give the correct cypher but only partially, such as CakGo[non ASCII character in place of N] instead of CaQGoN, or gives non ASCII characters in the cipher. I read in other threads' answers that this can be caused by the lack of a null-terminator or not considering the difference between lowercase and uppercase in the keyword, as such I wanted to know which one is the problem in my code.
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int shift(int keyword_num, string keyword);
int main(int argc, string argv[])
{
string keyword = argv[1];
// check for 2 arguments only
if (argc != 2)
{
printf("Usage: ./vigenere keyword\n");
return 1;
}
// check if argument is all alpha char (no punct)
for (int j = 0; j < strlen(argv[1]); j++)
{
if (!isalpha(argv[1][j]))
{
printf("Usage: ./vigenere keyword. Keyword must be a word\n");
return 1;
}
}
// Gets the plaintext that will be encrypted
string plaintext = get_string("Plaintext: ");
int keyword_num = 0;
printf("ciphertext: ");
for (int i = 0; i < strlen(plaintext); i++)
{
// Changes char depending on if it is uppercase, lowercase, or not a letter
// Note: 65 ASCII 'A', and 97 is ASCII 'a'
if islower(plaintext[i])
{
printf("%c", ((((plaintext[i] - 97) + shift(keyword_num, keyword) % 26) + 97)));
keyword_num++;
}
else if isupper(plaintext[i])
{
printf("%c", ((((plaintext[i] - 65) + shift(keyword_num, keyword) % 26) + 65)));
keyword_num++;
}
//if neither then print char as it is
else
{
printf("%c", plaintext[i]);
}
}
printf("\n");
//just to print the cipher in a non messy way that interfers with the next command
}
//function to the correspondind letter of the keyword
int shift(int keyword_num, string keyword)
{
int length = strlen(keyword);
return tolower(keyword[keyword_num % length]) - 97;
}