I am working on a code in which I shift each letter by one place, so (a) becomes (b) and (b) becomes (c) and so on. So far I managed to do that, but I am confronting a problem wrapping around the capital letter (Z) to (A). I can't seem to get the logic how to do that. Any help would be appreciated. Thanks a lot.
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
int main(void)
{
//prompt the user to type in a text.
string p = get_string("plaintext: ");
//create a variable to refer to the length of the string.
int n = strlen(p);
for (int i = 0; i < n; i++)
{
//check if all chars (i) in the string (p) are alphabetical then increment i by 1.
if (isalpha(p[i]))
p[i]++;
{
//check if i has gone beyond the letter (z) and (Z).
if ((p[i] > 'z') && (p[i] > 'Z'))
{
//if so then subtract 26 letter after z or Z to get back to a or A.
p[i] = p[i] - 26;
}
}
printf("%c", p[i]);
}
printf("\n");
}
an other way closer to the initial program is just to replace
if ((p[i] > 'z') && (p[i] > 'Z'))
by
if ((p[i] == 'z'+1) || (p[i] == 'Z'+1))
that avoid to duplicate almost all the code as this is the case in the other answer
And I think it is more readable to replace
p[i] = p[i] - 26;
by
p[i] -= 'z' - 'a' + 1;
The compiler replace 'z' - 'a' + 1
by its value and the expression explain the goal by itself
And to finish I think it is more clear to do
if (isalpha(p[i]))
{
if ((p[i] == 'z') || (p[i] == 'Z'))
p[i] -= 'z' - 'a';
else
p[i] += 1;
}
and that remove an increment for nothing
or to have only one line :
if (isalpha(p[i]))
p[i] += ((p[i] == 'z') || (p[i] == 'Z')) ? 'a' - 'z' : 1;
but this is less readable probably
Out of that
printf("%c", p[i]);
is expensive and can be replaced by
putchar(p[i]);