直接上代码:
/* 函数实现 */
char *my_itoa(int value, char *string, int radix)
{
const char ch[] = "0123456789abcdefghijklmnopqrstuvwxyz";/* 字符集 */
unsigned int uvalue = 0;
char *ptr = string;/* 操作指针 */
char *begin = NULL;/* 用于交换的起始指针 */
char *end = NULL;/* 用于交换的末尾指针 */
char temp = '\0';
assert(NULL != string && radix > 0);
/* 1、处理负数 */
if (value < 0 && 10 == radix)/* 十进制负数 */
{
uvalue = -value;
*ptr++ = '-';
}
else/* 其他情况,包括正数和非十进制负数 */
{
uvalue = (unsigned int)value;
}
begin = ptr;/* 起始指针 */
/* 2、倒序转换开始 */
while (uvalue)
{
*ptr++ = ch[uvalue% radix];
uvalue /= radix;
}
*ptr = '\0';
/* 倒序转换结束 */
end = ptr-1;/* 末尾指针 */
/* 3、首尾交换,使正序 */
while (begin < end)
{
temp = *begin;
*begin = *end;
*end = temp;
++begin;
--end;
}
return string;/* 返回 */
}
/* 测试函数 */
/*
* 注意事项:
* itoa并不是一个标准的C函数,它是Windows特有的,包含在<stdlib.h>头文件中,
* 请使用VC6.0编译,gcc无法编译通过。
*/
void test_my_itoa(void)
{
char str[128];
char my_str[128];
printf("Begin test my_itoa...\n");
memset(str, 0, sizeof(str));
memset(my_str, 0, sizeof(my_str));
assert(0 == strcmp(itoa(123,str,10), my_itoa(123,my_str,10)));/* 测试方法 */
memset(str, 0, sizeof(str));
memset(my_str, 0, sizeof(my_str));
assert(0 == strcmp(itoa(+123,str,10), my_itoa(+123,my_str,10)));
memset(str, 0, sizeof(str));
memset(my_str, 0, sizeof(my_str));
assert(0 == strcmp(itoa(-123,str,10), my_itoa(-123,my_str,10)));
memset(str, 0, sizeof(str));
memset(my_str, 0, sizeof(my_str));
assert(0 == strcmp(itoa(-123,str,8), my_itoa(-123,my_str,8)));
memset(str, 0, sizeof(str));
memset(my_str, 0, sizeof(my_str));
assert(0 == strcmp(itoa(-1234,str,13), my_itoa(-1234,my_str,13)));
memset(str, 0, sizeof(str));
memset(my_str, 0, sizeof(my_str));
assert(0 == strcmp(itoa(-1234,str,16), my_itoa(-1234,my_str,16)));
memset(str, 0, sizeof(str));
memset(my_str, 0, sizeof(my_str));
assert(0 == strcmp(itoa(123,str,20), my_itoa(123,my_str,20)));
memset(str, 0, sizeof(str));
memset(my_str, 0, sizeof(my_str));
assert(0 == strcmp(itoa(123,str,50), my_itoa(123,my_str,50)));
printf("End test my_itoa, successfully!\n");
}
Windows特有的itoa版本对于radix<=0的处理:
(1) radix == 0
测试代码片段:
memset(str, 0, sizeof(str));
printf("begin itoa(123,str,0)\n");
itoa(123,str,0);
printf("end itoa(123,str,0)\n");
测试结果:
函数运行异常。可见,Windows内置itoa并没有处理好radix == 0的情形。
(2) radix < 0
测试代码片段:
memset(str, 0, sizeof(str));
len = strlen(itoa(123,str,-12));
printf("len = %d\n", len);
for (i=0; i<len; ++i)
printf("\tstr[%d] = 0x%02x\n", i, str[i]);
memset(str, 0, sizeof(str));
len = strlen(itoa(123,str,-23));
printf("len = %d\n", len);
for (i=0; i<len; ++i)
printf("\tstr[%d] = 0x%02x\n", i, str[i]);
memset(str, 0, sizeof(str));
len = strlen(itoa(1234,str,-23));
printf("len = %d\n", len);
for (i=0; i<len; ++i)
printf("\tstr[%d] = 0x%02x\n", i, str[i]);
测试结果:
len = 1
str[0] = 0xffffffd2
len = 1
str[0] = 0xffffffd2
len = 1
str[0] = 0x29
可见,转换结果并无任何实际意义。所以自定义版本对radix<=0的情形做了如下统一处理:
assert(NULL != string && radix > 0);
即不处理,将radix<=0视为非法转换。