I'm trying to write a code that would convert letters into numbers. For example A ==> 0 B ==> 1 C ==> 2 and so on. Im thinking of writing 26 if statements. I'm wondering if there's a better way to do this...
Thank you!
This is a way that I feel is better than the switch
method, and yet is standards compliant (does not assume ASCII):
#include <string.h>
#include <ctype.h>
/* returns -1 if c is not an alphabetic character */
int c_to_n(char c)
{
int n = -1;
static const char * const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *p = strchr(alphabet, toupper((unsigned char)c));
if (p)
{
n = p - alphabet;
}
return n;
}
If you need to deal with upper-case and lower-case then you may want to do something like:
if (letter >= 'A' && letter <= 'Z')
num = letter - 'A';
else if (letter >= 'a' && letter <= 'z')
num = letter - 'a';
If you want to display these, then you will want to convert the number into an ascii value by adding a '0' to it:
asciinumber = num + '0';
The C standard does not guarantee that the characters of the alphabet will be numbered sequentially. Hence, portable code cannot assume, for example, that 'B'-'A'
is equal to 1.
The relevant section of the C specification is section 5.2.1 which describes the character sets:
3 Both the basic source and basic execution character sets shall have the following members: the 26 uppercase letters of the Latin alphabet
ABCDEFGHIJKLM NOPQRSTUVWXYZ
the 26 lowercase letters of the Latin alphabet
abcdefghijklm nopqrstuvwxyz
the 10 decimal digits
0123456789
the following 29 graphic characters
!"#%&'()*+,-./: ;<=>?[\]^_{|}~
the space character, and control characters representing horizontal tab, vertical tab, and form feed. The representation of each member of the source and execution basic character sets shall fit in a byte. 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.
So the specification only guarantees that the digits will have sequential encodings. There is absolutely no restriction on how the alphabetic characters are encoded.
Fortunately, there is an easy and efficient way to convert A to 0, B to 1, etc. Here's the code
char letter = 'E'; // could be any upper or lower case letter
char str[2] = { letter }; // make a string out of the letter
int num = strtol( str, NULL, 36 ) - 10; // convert the letter to a number
The reason this works can be found in the man page for strtol
which states:
(In bases above 10, the letter 'A' in either upper or lower case represents 10, 'B' represents 11, and so forth, with 'Z' representing 35.)
So passing 36 to strtol
as the base tells strtol
to convert 'A'
or 'a'
to 10, 'B'
or 'b'
to 11, and so on. All you need to do is subtract 10 to get the final answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With