0

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;
}

1 Answer 1

0

It doesn't seem to be either of those things (which you probably already verified). The root of the problem is operator precedence. Modulo % is "ranked" with multiplication and division. If you unwind one of the printf like this

    printf("%c",
     (
       (
         (
           (plaintext[i] - 65) + shift(keyword_num, keyword) % 26
         )
            + 65
       )
     )
   );

it might be easier to see that the operand of the % 26 is shift(keyword_num, keyword). The "wrap" (%26) needs to be applied after the character is shifted.

1
  • Thank you very much! I just altered the code so that "(plaintext[i] - 65) + shift(keyword_num, keyword)" was the operand and it worked. Such a simple thing I completely oversaw, I'll be more careful when adding lots of parenthesis. Jun 2, 2019 at 8:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .