Monday, April 25, 2011

Character to Integer in C

Is there a way to convert a character to an integer in C?

for example, '5' -> 5

thanks.

From stackoverflow
  • Subtract '0' like this:

    int i = c - '0';
    

    The C Standard guarantees each digit in the range '0'..'9' is one greater than its previous digit (in section 5.2.1/3 of the C99 draft). The same counts for C++.

    Arafangion : This answer would be better if you mentioned that a char is /already/ effectively an integer, albiet of implementation defined sign (ie, might be signed or unsigned), and is CHAR_BITS long.
    Johannes Schaub - litb : i wasn't sure knowing that really helps him. but Chris made a good point with a..z being not contiguous necessarily. i should have mentioned that instead. now he's won the race :)
    Arafangion : Yours is better because you've qualified your answer, though - Chris could very well have just made his stuff up. :)
    Johannes Schaub - litb : thanks for the appreciation. i admit i wasn't sure about the state for C. so i looked up and 'cause i already was at it i pasted the reference into the answer :)
    Arafangion : And that, sir, is why you've got a couple more points than me. :)
    Chris Young : I don't make stuff up. :p
    Johannes Schaub - litb : i believe you mate. i often find myself not pasting the reference to some standard section when giving answers either. but this time i looked up after answering and had the section numbers at hand, so it was easy to change my answer and add it in :) cheers
  • char numeralChar = '4';
    int numeral = (int) (numeralChar - '0');
    
    Alok : `numeralChar - '0'` is already of type `int`, so you don't need the cast. Even if it wasn't, the cast is not needed.
    Kevin Conner : Huh, yeah that would coerce, wouldn't it? Maybe Java has colored my perceptions. Or maybe I'm completely mistaken and it would even coerce in Java. :)
  • As per other replies, this is fine:

    char c = '5';
    int x = c - '0';
    

    Also, for error checking, you may wish to check isdigit(c) is true first. Note that you cannot completely portably do the same for letters, for example:

    char c = 'b';
    int x = c - 'a'; // x is now not necessarily 1
    

    The standard guarantees that the char values for the digits '0' to '9' are contiguous, but makes no guarantees for other characters like letters of the alphabet.

    Paul Tomblin : Will this work with EBCDIC or other non-ASCII encodings?
    Chris Young : @Paul Tomblin: Yes for digits not letters, because, as I said in the answer, the standard guarantees '0' to '9' are contiguous but does not make such guarantees for other characters such as 'a' to 'z'.
  • You would cast it to an int (or float or double or what ever else you want to do with it) and store it in anoter variable.

    SeanJA : Maybe I shouldn't have answered this one...
  • If it's just a single character 0-9 in ASCII, then subtracting the the value of the ASCII zero character from ASCII value should work fine.

    If you want to convert larger numbers then the following will do:

    char *string = "24";
    
    int value;
    
    int assigned = sscanf(string, "%d", &value);
    

    ** don't forget to check the status (which should be 1 if it worked in the above case).

    Paul.

  • char chVal = '5';
    char chIndex;
    
    if ((chVal >= '0') && (chVal <= '9')) {
    
        chIndex = chVal - '0';
    }
    else 
    if ((chVal >= 'a') && (chVal <= 'z')) {
    
        chIndex = chVal - 'a';
    }
    else 
    if ((chVal >= 'A') && (chVal <= 'Z')) {
    
        chIndex = chVal - 'A';
    }
    else {
        chIndex = -1; // Error value !!!
    }
    
  • If, by some crazy coincidence, you want to convert a string of characters to an integer, you can do that too!

    char *num = "1024";
    int val = atoi(num); // atoi = Ascii TO Int
    

    val is now 1024. Apparently atoi() is fine, and what I said about it earlier only applies to me (on OS X (maybe (insert Lisp joke here))). I have heard it is a macro that maps roughly to the next example, which uses strtol(), a more general-purpose function, to do the converstion instead:

    char *num = "1024";
    int val = (int)strtol(num, (char **)NULL, 10); // strtol = STRing TO Long
    

    strtol() works like this:

    long strtol(const char *str, char **endptr, int base);
    

    Converts *str to a long, treating it as if it were a base base number. If **endptr isn't null, it holds the first non-digit character strtol() found (but who cares about that).

    Evan Teran : There are no thread issues with atoi (it has no static data) and it is not deprecated. In fact it is functionally equivalent to: #define atoi(x) (int)(strtol((x), NULL, 10)
    Chris Lutz : Well damn. My manpages are old.
    David Thornley : The issue with atoi is that it uses 0 as a "can't find a number here" value, so atoi("0") and atoi("one") both return 0. If that doesn't work for what you're using it for, look for strtol() or sscanf().
  • Hi!

    is there a way that i can check if the input is either a int or a char?

    thanks,

  • When I need to do something like this I prebake an array with the values I want.

    const static int lookup[256] = { -1, ..., 0,1,2,3,4,5,6,7,8,9, .... };
    

    Then the conversion is easy

    int digit_to_int( unsigned char c ) { return lookup[ static_cast<int>(c) ]; }
    

    This is basically the approach taken by many implementations of the ctype library. You can trivially adapt this to work with hex digits too.

0 comments:

Post a Comment