Convert char to int in C and C++

2018-12-31 09:57发布

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

标签: c++ c gcc
11条回答
姐姐魅力值爆表
2楼-- · 2018-12-31 10:44

Well, in ASCII code, the numbers (digits) start from 48. All you need to do is:

int x = (int)character - 48;
查看更多
高级女魔头
3楼-- · 2018-12-31 10:44

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;
查看更多
何处买醉
4楼-- · 2018-12-31 10:44

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 chars 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.

查看更多
一个人的天荒地老
5楼-- · 2018-12-31 10:44

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.,

查看更多
美炸的是我
6楼-- · 2018-12-31 10:45

(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.

查看更多
登录 后发表回答