How do I convert a char
to an int
in C and C++?

- 112,946
- 110
- 377
- 526

- 7,905
- 10
- 36
- 44
-
1@Alf P. Steinbach: The original question was vague regarding which language. With keywords `c` and `c++`, I think answers confronting both languages are reasonable. – Matt Joiner Feb 17 '11 at 14:25
-
11From my extensive experience on other technical forums, my intuition is that the OP **really** means "how do I take the textual representation of a number (in base 10) and convert it to the corresponding number?" Generally speaking, C and C++ neophytes usually have **incredibly** fuzzy ideas about how text works in those languages and what `char` really means. – Karl Knechtel Feb 17 '11 at 15:56
-
4@KarlKnechtel: If that's true (I give it about 50/50 as lots of early tutorials also encourage getting ASCII values out of chars, even though ASCII doesn't cover the full range), the OP needs to clarity – but that's a dupe of http://stackoverflow.com/questions/439573/how-to-convert-a-single-char-into-an-int. – Fred Nurk Feb 17 '11 at 16:51
-
6The OP had three hours to clarify this question and failed to do so. As it is, there's no way to know what is actually asked. Voted to close. – sbi Feb 17 '11 at 17:27
-
Its probably a dup of something either way, actually... – T.E.D. Feb 17 '11 at 17:52
-
possible duplicate of [Character to Integer in C](http://stackoverflow.com/questions/628761/character-to-integer-in-c) – Helen Feb 17 '11 at 19:59
-
Note that even though you can do implicit casting back and forth when it comes to int and char, there are some really important things to know:1)depending on the situation you might loose the minus sign of your number (stored as a char) if you are not careful. That's why there is a signed and unsigned char;2)sizeof(char) = 1Byte (always; here I exclude the WIDE character, which can be more than 8bits) but sizeof(int) = at least 4Bytes! Char is an integer type with some restrictions. I advice you to avoid using char for math calculations unless you really have to. – rbaleksandar Jul 17 '13 at 03:21
14 Answers
Depends on what you want to do:
to read the value as an ascii code, you can write
char a = 'a';
int ia = (int)a;
/* note that the int cast is not necessary -- int ia = a would suffice */
to convert the character '0' -> 0
, '1' -> 1
, etc, you can write
char a = '4';
int ia = a - '0';
/* check here if ia is bounded by 0 and 9 */
Explanation:
a - '0'
is equivalent to ((int)a) - ((int)'0')
, which means the ascii values of the characters are subtracted from each other. Since 0
comes directly before 1
in the ascii table (and so on until 9
), the difference between the two gives the number that the character a
represents.
-
2@KshitijBanerjee That's not a good idea for two reasons: it gives you a negative number for ascii characters before '0' (like `&` -> -10), and it gives you numbers larger than 10 (like `x` -> 26) – SheetJS Dec 28 '14 at 18:14
-
3
-
5@kevin001 If you want to convert the char to int and a character `'1'` provides a ascii number that's not `1`, you need to remove the offset `'0'` to realign it to count from 0-9. The consecutive numbers 1-9 are adjacent in the ascii integer number. – krisdestruction Oct 09 '15 at 17:36
-
-
@foo-bah But I didn't understand why we have to subtract it with character '0', if we only typecast that character into integer and store it into integer, why it throws error.? – Srijoy_paul Mar 31 '21 at 12:22
C and C++ always promote types to at least int
. Furthermore character literals are of type int
in C and char
in C++.
You can convert a char
type simply by assigning to an int
.
char c = 'a'; // narrowing on C
int a = c;

- 208,748
- 37
- 389
- 560

- 112,946
- 110
- 377
- 526
-
3You could also use the sorely under-appreciated **unary** `operator+()` for this purpose. – Cubbi Feb 17 '11 at 14:14
-
25-1 The answer is incorrect for the only meaningful interpretation of the question. This (code `int a = c;`) will keep any negative values, which C standard library functions can't deal with. The C standard library functions set the standard for what it means to handle `char` values as `int`. – Cheers and hth. - Alf Feb 17 '11 at 14:14
-
@Nawaz - ...assuming he wants simple type hosing rather than an actual conversion. – T.E.D. Feb 17 '11 at 14:21
-
@Alf P. Steinbach: I disagree, that's beyond the scope of the question and assumes too much. Also note the addition of character literal interpretations are directed to @Sayam Ahmed's answer. This answer boils down to `int a = c;` as being enough. – Matt Joiner Feb 17 '11 at 14:26
-
6@Matt: I'm keeping the downvote. I'd strengthen it if possible! The question interpretation you and others have assumed is not meaningful, because it's too utterly trivial, and because for the OP's particular combination of types there is a not-so-trivial very important practical issue. The advice you give is directly **dangerous** to the novice. It will most likely result in **Undefined Behavior** for their programs that use C standard library character classification functions. Re ref. to @Sayam's answer, he has deleted that answer. – Cheers and hth. - Alf Feb 17 '11 at 15:22
-
3-1 for being incorrect: isupper() will have undefined results if passed a 1252 highbit character. – Chris Becke Feb 17 '11 at 15:34
-
1What do you mean by "always promote"? Values are promoted during implicit conversions, certain types of parameters passing (e.g., to a varargs function), and when an operator must makes its operands compatible types. But there are certainly times when a value is not promoted (like if a I pass a char to a function expecting a char), otherwise we wouldn't have any types smaller than an int. – Adrian McCarthy May 18 '13 at 19:44
-
-
QString::number(static_cast
(static_cast – smsware Mar 02 '20 at 14:58(arr.at(i))), 16) gave me the answer I was expecting, so I think many looking for an answer think like @Cheersandhth.-Alf refereed to - thank you, I upvoted Azeem's answer.
char is just a 1 byte integer. There is nothing magic with the char type! Just as you can assign a short to an int, or an int to a long, you can assign a char to an int.
Yes, the name of the primitive data type happens to be "char", which insinuates that it should only contain characters. But in reality, "char" is just a poor name choice to confuse everyone who tries to learn the language. A better name for it is int8_t, and you can use that name instead, if your compiler follows the latest C standard.
Though of course you should use the char type when doing string handling, because the index of the classic ASCII table fits in 1 byte. You could however do string handling with regular ints as well, although there is no practical reason in the real world why you would ever want to do that. For example, the following code will work perfectly:
int str[] = {'h', 'e', 'l', 'l', 'o', '\0' };
for(i=0; i<6; i++)
{
printf("%c", str[i]);
}
You have to realize that characters and strings are just numbers, like everything else in the computer. When you write 'a' in the source code, it is pre-processed into the number 97, which is an integer constant.
So if you write an expression like
char ch = '5';
ch = ch - '0';
this is actually equivalent to
char ch = (int)53;
ch = ch - (int)48;
which is then going through the C language integer promotions
ch = (int)ch - (int)48;
and then truncated to a char to fit the result type
ch = (char)( (int)ch - (int)48 );
There's a lot of subtle things like this going on between the lines, where char is implicitly treated as an int.
-
Since the question is not tagged with `ascii`, you should not assume any specific encoding. Setting`char` equal to `int8_t` is wrong because it could equally likely be `uint8_t` or `uint24_t`. – Roland Illig Mar 31 '18 at 20:18
-
3@RolandIllig No, a `char` is always 1 byte and if the types `int8_t`/`uint8_t` exist on the given system (which is very likely), they will be able to fit the result of a `char`, because it will then be 8 bits. On highly exotic systems such as various obsolete DSPs, `char` will be 16 bits and the `uint8_t` will not exist. Writing code for compatibility with obsolete DSPs is nonsense, as is writing for compatibility with one's complement or sign & magnitude systems. Huge waste of time, since such systems barely exist in the real world. – Lundin Apr 01 '18 at 20:11
(This answer addresses the C++ side of things, but the sign extension problem exists in C too.)
Handling all three char
types (signed
, unsigned
, and char
) is more delicate than it first appears. Values in the range 0 to SCHAR_MAX
(which is 127 for an 8-bit char
) are easy:
char c = somevalue;
signed char sc = c;
unsigned char uc = c;
int n = c;
But, when somevalue
is outside of that range, only going through unsigned char
gives you consistent results for the "same" char
values in all three types:
char c = somevalue;
signed char sc = c;
unsigned char uc = c;
// Might not be true: int(c) == int(sc) and int(c) == int(uc).
int nc = (unsigned char)c;
int nsc = (unsigned char)sc;
int nuc = (unsigned char)uc;
// Always true: nc == nsc and nc == nuc.
This is important when using functions from ctype.h, such as isupper
or toupper
, because of sign extension:
char c = negative_char; // Assuming CHAR_MIN < 0.
int n = c;
bool b = isupper(n); // Undefined behavior.
Note the conversion through int is implicit; this has the same UB:
char c = negative_char;
bool b = isupper(c);
To fix this, go through unsigned char
, which is easily done by wrapping ctype.h functions through safe_ctype:
template<int (&F)(int)>
int safe_ctype(unsigned char c) { return F(c); }
//...
char c = CHAR_MIN;
bool b = safe_ctype<isupper>(c); // No UB.
std::string s = "value that may contain negative chars; e.g. user input";
std::transform(s.begin(), s.end(), s.begin(), &safe_ctype<toupper>);
// Must wrap toupper to eliminate UB in this case, you can't cast
// to unsigned char because the function is called inside transform.
This works because any function taking any of the three char types can also take the other two char types. It leads to two functions which can handle any of the types:
int ord(char c) { return (unsigned char)c; }
char chr(int n) {
assert(0 <= n); // Or other error-/sanity-checking.
assert(n <= UCHAR_MAX);
return (unsigned char)n;
}
// Ord and chr are named to match similar functions in other languages
// and libraries.
ord(c)
always gives you a non-negative value – even when passed a negative char
or negative signed char
– and chr
takes any value ord
produces and gives back the exact same char
.
In practice, I would probably just cast through unsigned char
instead of using these, but they do succinctly wrap the cast, provide a convenient place to add error checking for int
-to-char
, and would be shorter and more clear when you need to use them several times in close proximity.
Use static_cast<int>
:
int num = static_cast<int>(letter); // if letter='a', num=97
Edit: You probably should try to avoid to use (int)
int num = (int) letter;
check out Why use static_cast<int>(x) instead of (int)x? for more info.

- 1
- 1

- 49,413
- 29
- 133
- 174
I have absolutely null
skills in C, but for a simple parsing:
char* something = "123456";
int number = parseInt(something);
...this worked for me:
int parseInt(char* chars)
{
int sum = 0;
int len = strlen(chars);
for (int x = 0; x < len; x++)
{
int n = chars[len - (x + 1)] - '0';
sum = sum + powInt(n, x);
}
return sum;
}
int powInt(int x, int y)
{
for (int i = 0; i < y; i++)
{
x *= 10;
}
return x;
}

- 302
- 3
- 8
-
4This code quickly invokes undefined behavior and is therefore not suitable for copy and pasting. (int overflow) – Roland Illig Mar 31 '18 at 20:25
It sort of depends on what you mean by "convert".
If you have a series of characters that represents an integer, like "123456", then there are two typical ways to do that in C: Use a special-purpose conversion like atoi() or strtol(), or the general-purpose sscanf(). C++ (which is really a different language masquerading as an upgrade) adds a third, stringstreams.
If you mean you want the exact bit pattern in one of your int
variables to be treated as a char
, that's easier. In C the different integer types are really more of a state of mind than actual separate "types". Just start using it where char
s are asked for, and you should be OK. You might need an explicit conversion to make the compiler quit whining on occasion, but all that should do is drop any extra bits past 256.

- 44,016
- 10
- 73
- 134
I recomend to use the following function:
/* chartoint: convert char simbols to unsigned int*/
int chartoint(char s[])
{
int i, n;
n = 0;
for (i = 0; isdigit(s[i]); ++i){
n = 10 * n + (s[i] - '0');
}
return n;
}
The result of function could be checked by:
printf("char 00: %d \r\n", chartoint("00"));
printf("char 01: %d \r\n", chartoint("01"));
printf("char 255: %d \r\n", chartoint("255"));

- 61
- 4
Presumably you want this conversion for using functions from the C standard library.
In that case, do (C++ syntax)
typedef unsigned char UChar;
char myCppFunc( char c )
{
return char( someCFunc( UChar( c ) ) );
}
The expression UChar( c )
converts to unsigned char
in order to get rid of negative values, which, except for EOF, are not supported by the C functions.
Then the result of that expression is used as actual argument for an int
formal argument. Where you get automatic promotion to int
. You can alternatively write that last step explicitly, like int( UChar( c ) )
, but personally I find that too verbose.
Cheers & hth.,

- 142,714
- 15
- 209
- 331
For char or short to int, you just need to assign the value.
char ch = 16;
int in = ch;
Same to int64.
long long lo = ch;
All values will be 16.

- 786
- 10
- 21
Use "long long" instead a "int" so it works for bigger numbers. Here the elegant solution.
long long ChardToint(char *arr, size_t len){
int toptenf=1;
long long toptenLf=10000000LL;
long long makeintf=3000000000000;
makeintf= 0LL;
int holdNumberf=0;
for(int i=len-1;i>=0 ;i--){
switch(arr[i]){
case '0':
holdNumberf=0;
break;
case '1':
holdNumberf=1;
break;
case '2':
holdNumberf=2;
break;
case '3':
holdNumberf=3;
break;
case '4':
holdNumberf=4;
break;
case '5':
holdNumberf=5;
break;
case '6':
holdNumberf=6;
break;
case '7':
holdNumberf=7;
break;
case '8':
holdNumberf=8;
break;
case '9':
holdNumberf=9;
break;
default:
holdNumberf=0;
}
if(toptenf>=10000000){
makeintf=makeintf+holdNumberf*toptenLf;
toptenLf=toptenLf*10;
}else{
makeintf=makeintf+holdNumberf*toptenf;
toptenf=toptenf*10;
}
}
return makeintf;
}

- 9
- 6
I was having problems converting a char array like "7c7c7d7d7d7d7c7c7c7d7d7d7d7c7c7c7c7c7c7d7d7c7c7c7c7d7c7d7d7d7c7c2e2e2e"
into its actual integer value that would be able to be represented by `7C' as one hexadecimal value. So, after cruising for help I created this, and thought it would be cool to share.
This separates the char string into its right integers, and may be helpful to more people than just me ;)
unsigned int* char2int(char *a, int len)
{
int i,u;
unsigned int *val = malloc(len*sizeof(unsigned long));
for(i=0,u=0;i<len;i++){
if(i%2==0){
if(a[i] <= 57)
val[u] = (a[i]-50)<<4;
else
val[u] = (a[i]-55)<<4;
}
else{
if(a[i] <= 57)
val[u] += (a[i]-50);
else
val[u] += (a[i]-55);
u++;
}
}
return val;
}
Hope it helps!
-
1Have you ever tested this code? The 50 should be a 48, the 55 only works for uppercase ASCII letters while your example contains lowercase letters. – Roland Illig Mar 31 '18 at 20:32
int charToint(char a){
char *p = &a;
int k = atoi(p);
return k;
}
You can use this atoi method for converting char to int. For more information, you can refer to this http://www.cplusplus.com/reference/cstdlib/atoi/ , http://www.cplusplus.com/reference/string/stoi/.

- 81
- 5
-
3This is undefined behavior. Taking the address of a char variable will give you a char* but not a C-string, which is what atoi expects. – luizfls Feb 29 '20 at 00:44