Kim Kim - 4 months ago 72
C Question

CS50 Pset2. Vigenere. Upper text to lower key and vice versa problems

Okay. So, I need to make a Vigenere cypher. When the text and key are both upper case of both lower case, the code compiles fine. But when the text and the key differ from case, the code is not working. Then it doesn't print anything. For example when the key is: aaAA. And the text is aBcD. The outcome is: aD. Can someone give me a hint, please? :)

#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

int main (int argc, string argv[])
{
string key = argv [1]; //argv [1] is the key. 0 is compile program
{
if (argc != 2)
{
printf ("Please give one key: "); //if there are more or less then 2 argc, then have to try again
}

for (int j = 0, n = strlen (key); j < n; j++)
if (!isalpha (key [j]))
{
printf ("Please give a key in alphabetic characters: ");
//key must be alphabetic. For loop to check every character of the key.
return 1;
}
}

string text = GetString(); //Get secret message from user

int j = 0;
for (int i = 0, n = strlen (text); i < n; i++)
{
if (isupper (text [i]))
{
if (isupper (key [j]))
{
/*Minus 65 to make count till 26 from text and key. Use modulo to wrap around key. And modulo to wrap around alphabet.
Plus 65 to go to correct ASCII character. */
int u = ((((text [i] - 65) + (key [j % strlen (key)] - 65)) % 26) + 65);
printf ("%c", u);
}
}
else if (islower (text [i]))
{
if (islower (key[j]))
{
int l = ((((text [i] - 97) + (key [j % strlen (key)] - 97)) % 26) + 97);
printf ("%c", l);
}
}
else if (islower (text [i]))
{
if (isupper (key[j]))
{
int lu = ((((text [i] - 97) + (key [j % strlen (key)] - 65)) % 26) + 97);
printf ("%c", lu);
}
}
else if (isupper (text [i]))
{
if (islower (key[j]))
{
int ul = ((((text [i] - 65 + (key [j % strlen (key)] - 97)) % 26) + 65);
printf ("%c", ul);
}
}
else
{
// When character is non alphabetic print it in its original form.
printf ("%c", text [i]);
}
j++;
}
{
printf ("\n");
return 0;
}
}



Answer

The problem is in your if, else-if, else-if... statements. The reason is cause if isupper(text[i]) returns true, and if isupper(key[j]) returns false it will never evaluate the else if statements. You should do this

if( isupper(text[i])){
    if(isupper(key[j])){ // Both upper
       //do stuff
    }
    else if(islower(key[j])){ //Here key is lower and text is upper
       //do stuff
    }
}
else if (islower(text[i])){
    if (islower(key[j])){ //Both lower
        //do stuff
    }
    else if(isupper(key[j])){ //Key upper and text lower
        //do stuff
    }
}
else{//It's not alpha
    //do stuff
}

/***************NEW********************/
j = j%strlen(key); //I suggest using this at the end of the loop to avoid key[j] to go out of it's bounds
// j = (j==strlen(key)) ? 0 : j; //Another alternative

Also, I think you shouldn't be increasing j if the character is not alpha

Comments