PS2 Caesar Algorithm

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

int main (int argc, string argv[])

{
//Terminates if Command-line Arguement not provided.
if (argc != 2)
{
printf("command line arguement invalid or missing\n");
return 1;
}

//Iterates over Command-line Arguement to check if it's Numeric.
else
{
for (int i = 0; i < strlen(argv); i++)

if (!isdigit(argv[i]))
{
printf("Not a number\n");
return 1;
}

printf ("Success\n%s\n", argv);
}

int k = atoi(argv);

//Gets the Plain-Text from the user
string ptxt = get_string("Plain Text: ");

//Iterate over plain-text to shift letters & print cyphertext
printf("Cyphertext: ");
for (int i = 0; i < strlen(ptxt); i++)
{
if (isalpha(ptxt[i]))
{
if (ptxt[i] >= 'Z' && isupper(ptxt[i]))
{
printf("%c", ((ptxt[i] + k) - 'A') % 26);
}

else if (ptxt[i] >= 'z' && islower(ptxt[i]))
{
printf("%c", ((ptxt[i] + k) - 'a') % 26);
}
}

else
{
printf("%c", (ptxt[i]));
}
}
printf("\n");

}

Guys I believe my algorithm is fine at and onwards

if (ptxt[i] >= 'Z' && isupper(ptxt[i]))
{
printf("%c", ((ptxt[i] + k) - 'A') % 26);

but it is still not working. I have spent hours trying to figure out but it can't seem to work for me.

It only works perfect if I code inside the printf like this

//Iterate over plain-text to shift letters & print cyphertext
printf("Cyphertext: ");
for (int i = 0; i < strlen(ptxt); i++)
{
if (isalpha(ptxt[i]) && isupper(ptxt[i]))
{
printf("%c", (((ptxt[i] + k) - 'A') % 26) + 'A');
}

else if (islower(ptxt[i]))
{
printf("%c", (((ptxt[i] + k) - 'a') % 26 ) + 'a' );
}

else
{
printf("%c", (ptxt[i]));
}
}
printf("\n");

}

Why not this one working??

if (isalpha(ptxt[i]))
{
if (ptxt[i] >= 'Z' && isupper(ptxt[i]))
{
printf("%c", ((ptxt[i] + k) - 'A') % 26);
}

else if (ptxt[i] >= 'z' && islower(ptxt[i]))
{
printf("%c", ((ptxt[i] + k) - 'a') % 26);
}
}

else
{
printf("%c", (ptxt[i]));
}
}
printf("\n");

}

I want to know why this code is not working for learning purposes. Thanks

EDITED: This code works fine with if 'Z' and 'z'.

if (isalpha(plaintext[i]))
{
//int c = plaintext[i] + key;

ciphertext[i] = plaintext[i] + key;
if (plaintext[i] >= 'Z' && isupper(plaintext[i]))
{
ciphertext[i] = ((plaintext[i] + key) - 'A') % 26;
}
else if (plaintext[i] >= 'z' && islower(plaintext[i]))
{
ciphertext[i] = ((plaintext[i] + key) + 'a') % 26;
}

}
else
{
ciphertext[i] = plaintext[i];
}
}
}
printf("%s\n", ciphertext);

The only time this if (ptxt[i] >= 'Z' && isupper(ptxt[i])) will evaluate to true is when ptxt[i] is 'Z'. There is no other (upper case) letter that can be both. (Similarly this else if (ptxt[i] >= 'z' && islower(ptxt[i])) is only true for 'z').

Think about why isupper() and islower() are sufficient. Remember too that if isupper() or islower() is true then isalpha() must be true.

Another big (huge) difference between the two versions (in the original post) is in the math:

printf("%c", (((ptxt[i] + k) - 'A') % 26) + 'A'); //works

printf("%c", ((ptxt[i] + k) - 'A') % 26); //doesn't work

The second one will produce results outside the ascii range of the alphabetic characters.

The EDITED version "works" with the z tests because of ciphertext[i] = plaintext[i] + key;. It is doing the test after the key is applied.

• I got what you are saying but please see the the code in Edited section of my post. The 'Z' and 'z' there works fine in if condition. And the code works as it should there. Really confusing for me why my code doesn't work with if condition applied. Please guide Jan 22 '20 at 4:38