5

Possible Duplicate:
Char to int conversion in C.

I remember learning in a course a long time ago that converting from an ASCII char to an int by subtracting '0' is bad.

For example:

int converted;
char ascii = '8';

converted = ascii - '0';

Why is this considered a bad practice? Is it because some systems don't use ASCII? The question has been bugging me for a long time.

Community
  • 1
  • 1
David
  • 216
  • 2
  • 10
  • 3
    This isn't a duplicate because the referenced question is language agnostic question about all encodings. This is specific to C which provides additional guarantees. – CB Bailey Jul 01 '10 at 19:22
  • I would have trouble answering this, because it isn't a bad practice, whatever character set is used is required to have '0'..'9' contiguous, and I don't know enough about your course to criticize it properly (except for teaching you something wrong). – David Thornley Jul 01 '10 at 19:48
  • @Charles: It is, however, a duplicate of http://stackoverflow.com/questions/781668/char-to-int-conversion-in-c. – David Thornley Jul 01 '10 at 19:49
  • @David Thornley: indeed it is; voting to close. – CB Bailey Jul 01 '10 at 19:52

3 Answers3

7

While you probably shouldn't use this as part of a hand rolled strtol (that's what the standard library is for) there is nothing wrong with this technique for converting a single digit to its value. It's simple and clear, even idiomatic. You should, though, add range checking if you are not absolutely certain that the given char is in range.

It's a C language guarantee that this works.

5.2.1/3 says:

In both the source and execution basic character sets, the value of each character after 0 in the above list [includes the sequence: 0,1,2,3,4,5,6,7,8,9] shall be one greater that the value of the previous.

Character sets may exist where this isn't true but they can't be used as either source or execution character sets in any C implementation.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
3

Edit: Apparently the C standard guarantees consecutive 0-9 digits.

ASCII is not guaranteed by the C standard, in effect making it non-portable. You should use a standard library function intended for conversion, such as atoi. However, if you wish to make assumptions about where you are running (for example, an embedded system where space is at a premium), then by all means use the subtraction method. Even on systems not in the US-ASCII code page (UTF-8, other code pages) this conversion will work. It will work on ebcdic (amazingly).

Yann Ramin
  • 32,895
  • 3
  • 59
  • 82
  • I don't atoi() would help here, since it would convert "3" to a 3, not to the ascii code. I also don't think it would convert "a" to its ASCII – Uri Jul 01 '10 at 19:13
  • 1
    atoi() won't work on a single character, it needs a null-terminated string. – Fred Larson Jul 01 '10 at 19:17
  • 3
    ascii is not guaranteed but the fact that the values of '0' to '9' are consecutive integers is. – CB Bailey Jul 01 '10 at 19:40
0

This is a common trick taught in C classes primarily to illustrate the notion that a char is a number and that its value is different from the corresponding int.

Unfortunately, this educational toy somehow became part of the typical arsenal of most C developers, partially because C doesn't provide a convenient call for this (it is often platform specific, I'm not even sure what it is).

Generally, this code is not portable for non-ASCII platforms, and for future transitions to other encodings. It's also not really readable. At a minimum wrap this trick in a function.

Uri
  • 88,451
  • 51
  • 221
  • 321
  • 2
    It *is* portable to non-ASCII platforms because it is a language requirement that the values '0' to '9' are consecutive. – CB Bailey Jul 01 '10 at 19:21