I am finishing the Caesar program in Problem Set 2 and, most of the time, my code works as intended - enciphering the user's input by incrementing each character by the integer entered at the command line (argv[1]). What I cant seem to explain or figure out is the fact that, though entering "z" or "zaz" will return "a" or "aba", respectively, entering "Z" or "ZAZ" will return "A[" or "A[BA[", respectively, when the command line integer is "1".
This output occurs despite the fact that the code for converting "z" to "a" is exactly the same as the code for converting "Z" to "A". Any help would be greatly appreciated. The code for the program is as follows:
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, string argv[])
{
//check to ensure argv[1] is an integer
int m = strlen(argv[1]);
char input[m];
strcpy(input, argv[1]);
int check = 0;
for(int j = 0; j < m; j++)
{
if(isdigit(input[j]) == 0)
{
check++;
}
}
// if only two command line arguments entered, and arg[v] is a non-
// negative integer, proceed
if((argc == 2) && (atoi(argv[1]) >= 0) && (check == 0))
{
// initialize key used to increment/encipher user's input
int key = (atoi(argv[1]) % 26);
// prompt user for plaintext to be enciphered
printf("Plaintext: ");
string ptext = get_string();
int n = strlen(ptext);
printf("Ciphertext: ");
// iterate over plaintext input
for(int i = 0; i < n; i++)
{
if(isalpha(ptext[i]))
{
// circle back to beginning of capital alphabet if increment
// passes "Z"
if(117 > (ptext[i] + key) && (ptext[i] + key) > 90)
{
printf("%c", (ptext[i] + key - 26));
}
// circle back to beginning of lowercase alphabet if increment
// passes "z"
if(149 > (ptext[i] + key) && (ptext[i] + key) > 122)
{
printf("%c", (ptext[i] + key - 26));
}
else
{
printf("%c", (ptext[i] + key));
}
}
// print non-letters as entered by user
else
{
printf("%c", ptext[i]);
}
}
printf("\n");
return 0;
}
else
{
printf("Error, input must be single command line argument (non-negative integer).\n");
return 1;
}
}
As said earlier, entering "1" at the command line (or 53, 79, etc.) will change "z" to "a", as intended. I'm wondering why, in the same situation and moreover, using the same code, entering "1" at the command line changes "Z" to "A[".
I'd be grateful if anyone could explain. Thank you!
Edit: For what it's worth, the issue seems to be about passing "Z" in the capital alphabet. When the command line integer is "3", "X" changes to "A[", when the integer is "2", "Y" changes to "A[", and so on. Interestingly (?), when the integer is "2", "Z" changes to "B\", and when the integer is "3", "Z" changes to "C]". So, for some reason, it appears to be printing the ASCHII value (e.g. Z + 1 = [) after circling back to the beginning of the alphabet and printing the intended letter. Despite the code being the same, none of these issues occur with the lowercase letters - i.e. integer of "1" changes "z" to "a", and not "a{".
Edit 2: I got the job accomplished by changing the code dealing with "passing Z/z" entirely. If anyone has any theories on why this occurred to begin with, though, I'd love to hear them and better understand what the issue was.