Path: utzoo!attcan!uunet!nih-csl!lhc!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.lang.c Subject: Re: Summary: Converting ascii hex to pure hex values Message-ID: <27217@mimsy.umd.edu> Date: 26 Oct 90 22:30:19 GMT References: <302@cti1.UUCP> Distribution: comp Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 102 In article <302@cti1.UUCP> mpledger@cti1.UUCP (Mark Pledger) writes: >I sure caused alot of traffic for this little question. >I guess I did'nt make myself clear enough on my question though. Indeed. >Without using scanf() (or even sprintf()) what is the best (fasted >for me) way to convert a two-digit ascii code to a one digit hex code >so I can put it back into the charater string s[], append a null, and >write it back out to disk. This question is *still* confused. The Miriam-Webster dictionary defines `code' with four meanings. The one relevant to this discussion is number 3, `a system of signals', or number 4, `a system of symbols or letters used (as in secret communication or in a computing machine) with special meanings' (the latter is more intended to refer to encryption codes and instruction codes, I think). In either case, there is no such thing as a `one digit hex code'. Hexadecimal is a base, not a value, and as such any number of hexadecimal digits might be required to represent any particular value. Since hexadecimal is base sixteen, a single hexadecimal digit can represent one of the values from the set {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15} (where these values are coded in decimal). Two hex digits can represent a value in the range [0..255] (where the `[x..y]' notation implies `all integer values in the range given with the lower bound x on the left and the upper bound y on the right, inclusive of both bounds'). Now, as it happens, an eight bit byte, as is found on the most common computers these days, can also represent a value in the range [0..255]. The phrase `two-digit ASCII code', however, suggests a pair of values from the set ['0'..'9'], which can represent at most 100 distinct values (usually the set [0..99]). I.e., we have an ASCII encoding of an integral value in [0..99]. There is no way this can be represented with a single hexadecimal digit. On the other hand, the phrase `two-digit ASCII code' in close proximity to `hex code' suggests that perhaps what is meant is a pair of values from the set {['0'..'9'],['A'..'F']} (or the same but with lowercase). Such a pair can represent at most 256 distinct values, usually the set [0..255]. Coincidentally this corresponds exactly to the set of values that can be represented by an (unsigned) eight bit byte. But Mr. Pledger goes on to say: >I currently use atoi() and just write out the int to disk. This suggests that the guess that `two ASCII digits' means `two ASCII hexadecimal digits' (i.e., the set including the letters A through F, rather than just the decimal digits zero through nine) is incorrect. Now we are back to the concept of `two ASCII decimal digits', or a printable ASCII representation of a value in the range [0..99]. We can now be fairly confident that what is desired is to take two characters, each of which is guaranteed to be in the range ['0'..'9'], and come up with an integer value in the range [0..99] according to the obvious mapping ... until we reach his final sentence: >I am interested in ... a routine that will take a character string as the >argument, and returning the hex result in the same character string. But `hex', as noted above, is a particular ENCODING of a value. It is not a RESULT---the result of transforming two decimal ASCII digits to a value is an integer in the range [0..99], and has nothing at all to do with hexadecimal encodings. Is it any wonder that such a question generates a multitude of answers? There is no correct answer; the question is rather like asking how to construct a circle with four sides. Now, if all you want to do is convert an ASCII decimal representation of a value to a binary value stored in a single `char', with the `char' being the first of the set of `char's that held the original ASCII decimal representation---and assuming that the original ASCII sequence is ended with a NUL (character 0) or a non-digit, you can simply write: void foo(char *s) { *s = atoi(s); } If you want the original ASCII sequence modified so that the result is still a NUL-terminated string, you can add one more statement: void foo(char *s) { *s = atoi(s); s[1] = 0; } If you want to take pairs of ASCII decimal digits and convert each pair (with exactly two, no more and no fewer, required) into binary values and store those in the original string, you can change this to: void foo(char *s) { char *out = s; while (isdigit(*s) && isdigit(s[1])) { *out++ = (*s - '0') * 10 + s[1] - '0'; s += 2; } *out = 0; } If you want something else, you will have to figure out what it is first. There is no such thing as a `pure hexadecimal value', because hexadecimal is a representation, not a value. (Ask yourself just what an `impure hexadecimal value' might be.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris