underneath, chars are ints, they all have a numeric value. If you take the letter input, convert it to upper or lower case using tolower() or toupper() then subtract the desired amount to leave a number so that they character map onto the numbers you want.
Although using ASCII codes is generally valid, it is not universal. The C99 standard requires that the digit characters ('0'-'9') are consecutive but not the letter characters: "In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous.". EBCDIC is perfectly valid, even though its alphabet is disjointed, meaning this code will not work universally.
If you aren't worried about developing for IBM mainframes using EBCDIC quirkyusername's approach is fine. If you are, use a switch statement.