其实atoi比较简单些。一般处理也简单(无须考虑基数等问题,默认10为底),无非要注意符号的处理和可能的空格处理。
#include <ctype.h>
int yang_atoi ( const char * str )
{
int n=0;
int sign;
char *p = (char *)str;
while(isspace(*p))
++p;
sign = (*p == '-')?-1:1;
if((*p == '+')||(*p)=='-')
++p;
while(isdigit(*p))
n = 10 *n + (*p++ - '0');
return sign > 0 ? n : -n;
}
itoa的比较复杂些,其默认原型为
char * itoa ( int value, char * result, int base )
很可惜,其在Linux下无相应的实现。官方给出建议是可以用sprintf实现。
/*
* A standard-compliant alternative for some cases may be sprintf:
* */
当然,sprintf只能有8,10,16相应的版本给出。
sprintf(str,"%d",value) converts to decimal base.
sprintf(str,"%x",value) converts to hexadecimal base.
sprintf(str,"%o",value) converts to octal base.
所以还是有必要实现下的。
基本思路是数学上的知识,在此不表,最后保存的字符串要翻转,才是我们正常读的方式。
ps:非常坑爹的是Linux下strrev也没有实现,哎。自己动手实现了一个非标准的——扩展成strrev也方便。
void strreverse(char* begin, char* end)
{
char aux;
while(begin < end)
aux=*end, *end--=*begin, *begin++=aux;
}
strrev版本
#include <string.h>
void strrev(char* str)
{
size_t len = strlen(str);
strreverse(str,str+len-1);
}
itoa的最终版本
/*
* A standard-compliant alternative for some cases may be sprintf:
* */
char * yang_itoa ( int value, char * result, int base )
{
static const char * str = "0123456789abcdef";
char * ptr = result;
int sign = 1;
if((base < 2 )||(base > 16))
*result = '\0';
if(value < 0)
value = -value,sign = -1;
do{
*ptr++ = str[value % base];
value /= base;
}while(value);//while(value =/base);
if((sign < 0 )&&(base == 10))
*ptr++ = '-';
if(!(base % 16))
*ptr ++ = 'x';
if(!(base % 8))
*ptr++ ='0';
*ptr = '\0';
strreverse(result,ptr-1);
return result;
}
该版本给出了当为十六进制的时候类似输出0x6b。
找到一个版本
http://www.strudel.org.uk/itoa/
View Code
/**
* C++ version 0.4 char* style "itoa":
* Written by Lukás Chmela
* Released under GPLv3.
*/
char* itoa(int value, char* result, int base) {
// check that the base if valid
if (base < 2 || base > 36) { *result = '\0'; return result; }
char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do {
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
} while ( value );
// Apply negative sign
if (tmp_value < 0) *ptr++ = '-';
*ptr-- = '\0';
while(ptr1 < ptr) {
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
return result;
}