Trying to create a Caesar Cypher in C and getting some troublesome output from lowercase letters that exceed 'z' when shifting letters
#include <stdio.h>
void confab(const char* inText, int shift, char* outText)
{
int i = 0;
int j = 0;
char character = '\0';
while (inText[i] != '\0') {
if (inText[i] >= 'A' && inText[i] <= 'Z') {
character = inText[i] + shift;
if (character > 'Z') {
character = character - 'Z' + 'A' - 1;
}
outText[j] = character;
j += 1;
} else if (inText[i] >= 'a' && inText[i] <= 'z') {
character = inText[i] + shift;
if (character > 'z') {
character = (character - 'z' + 'a' - 1);
}
outText[j] = character;
j += 1;
} else {
outText[j] = inText[i];
j += 1;
}
i += 1;
}
}
int main(void)
{
char buffer[60] = {0};
char* s = "The quick brown fox jumps over the lazy dog.";
confab(s, 13, buffer);
printf("%s\n", buffer);
}
Is giving the output:
Gur d\202vpx oeb\204a sb\205 w\202zc\200 b\203re \201ur yn\207\206 qbt.
Instead of:
Gur dhvpx oebja sbk whzcf bire gur ynml qbt.
Suspecting my ASCII arithmetic is off in that if statement for the lowercase letters.
The problem with your code is that character
variable is declared as signed 1-byte number.
So by looking at the ASCII table, a-z
are in the range of 97-122. The problem is when you're trying to shift more than 5, it will overflow because signed 1-byte number can't exceed 127.
So by changing char character = '\0';
to unsigned char character = '\0';
will do the job.
You can refer here for the maximum number of integer for any byte - https://en.wikipedia.org/wiki/Integer_(computer_science)#Common_integral_data_types