Your code doesn't take into account the lowercase part of the alphabet.
To fix that, you can do:
//encrypts in place; I've replaced the magic numbers with their char-literal-based derivations
void encrypt(char *plain, int key)
{
#define cypher plain[i]
size_t i, n, index;
for (i = 0, n = strlen(plain); i < n; i++)
{
if (isupper (plain [i]))
{
index = plain [i] - 'A';
cypher = ((index + key) % ('Z'-'A'+1) ) + 'A';
}else if(islower(plain[i])){
index = plain [i] - 'a';
cypher = ((index + key) % ('z'-'a'+1)) + 'a';
}else
cypher=plain[i];
}
}
or, if you're limiting yourself to ASCII, you can speed things up by replacing the locale-based ctype macros
with simple char comparisons. If you're further willing to accept as encoding sources/targets the [\]^ _
characters in between the A-Z and a-z range in ascii you could further simplify to
void encrypt(char *plain, int key)
{
#define cypher plain[i]
size_t i, n, index;
for (i = 0, n = strlen(plain); i < n; i++)
{
if(plain[i] >= 'A' && plain[i] <='z'){
index = plain [i] - 'A';
cypher = ((index + key) % ('z'-'A'+1) ) + 'A';
} else cypher=plain[i];
}
}
Example usage (with either version):
int main(int c, char **v)
{
char s[]="Hello, World!";
encrypt(s,3);
puts(s);
encrypt(s,-3);
puts(s);
}
Sample run:
$ ./a.out
Khoor, Zruog!
Hello, World!