Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting Letters to Numbers in C

Tags:

c

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!

like image 254
user133466 Avatar asked Sep 24 '09 04:09

user133466


3 Answers

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;
}
like image 155
caf Avatar answered Sep 17 '22 13:09

caf


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';
like image 34
James Black Avatar answered Sep 19 '22 13:09

James Black


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.

like image 27
user3386109 Avatar answered Sep 17 '22 13:09

user3386109