shaobin0604
10/30/2009 - 4:14 AM

tcpl_ex-2-3.c

/*
 * Exercise 2-3. Write a function  htoi(s), which converts a string of hexadecimal 
 * digits (including an optional 0x or 0X) into its equivalent integer value. The 
 * allowable digits are 0 through 9, a through f, and A through F.  
 */
#include <stdio.h>
#include <stdlib.h>
#define BASE  16
#define TRUE  1
#define FALSE 0

int hexdigit(char c) {
	if (c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F') 
		return TRUE;
	else
		return FALSE;
}

unsigned int converthex(char c) {
	if (c >= '0' && c <= '9')
		return c - '0';
	else if (c >= 'a' && c <= 'f')
		return c - 'a' + 10;
	else if (c >= 'A' && c <= 'F')
		return c - 'A' + 10;
}

unsigned int htoi(const char s[]) {
	int  i = 0;
	unsigned int result = 0;
	if ('0' == s[i]) {	/* skip optional 0x or 0X */
		i++;
		if ('x' == s[i] || 'X' == s[i])
			i++;
	}

	while (1) {
		if (hexdigit(s[i]))
			result = result * BASE + converthex(s[i]);
		else
			break;
		++i;
	}

	return result;
}

int main(void)
{
	char *endp = NULL;
	char *test[] =
	{
		"F00",
		"bar",
		"0100",
		"0x1",
		"0XA",
		"0X0C0BE",
		"abcdef",
		"123456",
		"0x123456",
		"deadbeef",
		"zog_c"
	};
	unsigned int result;
	unsigned int check;

	size_t numtests = sizeof(test) / sizeof(test[0]);
	size_t thistest;

	for (thistest = 0; thistest < numtests; thistest++) {
		result = htoi(test[thistest]);
		check = (unsigned int)strtoul(test[thistest], &endp, 16);
		if ((*endp != '\0' && result == 0) || result == check)
			printf("Testing %s. Correct. %u\n", test[thistest], result);
		else
			printf("Testing %s. Incorrect. %u\n", test[thistest], result);
	}
	return 0;
}