atoi: 把字符串转换成整型数
itoa: 把整数转换为字符串
/*example of atoi and itoa*/
#include <stdlib.h>
#include <stdio.h>
{
int main(void)
int number = 12345;
char string[25];
itoa(number, string, 10);
printf("integer = %d string = %s\n", number, string);
return 0;
}
- char* itoa(int value,char*string,int radix);
#include <stdlib.h>
int to array
example of itoavalue: 要转换的整数
string: 转换后的字符串
radix: 转换进制数,如2,8,10,16 进制等。
#include <stdlib.h>
#include <stdio.h>
int main()
{
int number1 = 123456;
int number2 = -123456;
char string[16] = {0};
itoa(number1,string,10);
printf("数字:%d 转换后的字符串为:%s\n",number1,string);
itoa(number2,string,10);
printf("数字:%d 转换后的字符串为:%s\n",number2,string);
return 0;
}
函数源码:
/*itoa in lib*/
char* itoa(int num,char* str,int radix)
{
char index[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//索引表
unsigned unum;//存放要转换的整数的绝对值,转换的整数可能是负数
int i=0,j,k;//i用来指示设置字符串相应位,转换之后i其实就是字符串的长度;转换后顺序是逆序的,有正负的情况,k用来指示调整顺序的开始位置;j用来指示调整顺序时的交换。
//获取要转换的整数的绝对值
if(radix==10&&num<0)//要转换成十进制数并且是负数
{
unum=(unsigned)-num;//将num的绝对值赋给unum
str[i++]='-';//在字符串最前面设置为'-'号,并且索引加1
}
else unum=(unsigned)num;//若是num为正,直接赋值给unum
//转换部分,注意转换后是逆序的
do
{
str[i++]=index[unum%(unsigned)radix];//取unum的最后一位,并设置为str对应位,指示索引加1
unum/=radix;//unum去掉最后一位
}while(unum);//直至unum为0退出循环
str[i]='\0';//在字符串最后添加'\0'字符,c语言字符串以'\0'结束。
//将顺序调整过来
if(str[0]=='-') k=1;//如果是负数,符号不用调整,从符号后面开始调整
else k=0;//不是负数,全部都要调整
char temp;//临时变量,交换两个值时用到
for(j=k;j<=(i-1)/2;j++)//头尾一一对称交换,i其实就是字符串的长度,索引最大值比长度少1
{
temp=str[j];//头部赋值给临时变量
str[j]=str[i-1+k-j];//尾部赋值给头部
str[i-1+k-j]=temp;//将临时变量的值(其实就是之前的头部值)赋给尾部
}
return str;//返回转换后的字符串
}
- int atoi(const char *str)
#include <stdlib.h>
array to int
example of atoistr 要转换为整数的字符串。
返回值
该函数返回转换后的长整数,如果没有执行有效的转换,则返回零。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int val;
char str[20];
strcpy(str, "98993489");
val = atoi(str);
printf("字符串值 = %s, 整型值 = %d\n", str, val);
strcpy(str, "runoob.com");
val = atoi(str);
printf("字符串值 = %s, 整型值 = %d\n", str, val);
return(0);
}
函数源码:
/*itoa in lib*/
int atoi(const char *nptr)
{
return (int) strtol(nptr, (char **) NULL, 10);
}
long __XL(strtol)(const char * __restrict str, char ** __restrict endptr,
int base __LOCALE_PARAM )
{
return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 1 __LOCALE_ARG );
}
// 下述函数才是真正完成任务的函数
// 实际调用时, str 是输入的nptr, endptr 是 NULL, base 是 10, sflag 是 1
// 即 unsigned long _XL_NPP(_stdlib_strto_l)(nptr, NULL, 10, 1)
unsigned long __XL_NPP(_stdlib_strto_l)(register const Wchar * __restrict str,
Wchar ** __restrict endptr, int base,
int sflag __LOCALE_PARAM )
{
unsigned long number, cutoff;
#if _STRTO_ENDPTR
const Wchar *fail_char;
#define SET_FAIL(X) fail_char = (X)
#else
#define SET_FAIL(X) ((void)(X)) /* Keep side effects. */
#endif
unsigned char negative, digit, cutoff_digit;
assert(((unsigned int)sflag) <= 1);
SET_FAIL(str);
while (ISSPACE(*str)) { /* 忽略str中开头的空格 */
++str;
}
/* 0 代表 正数; 1 代表 负数 */
negative = 0;
switch(*str) {
/* 注意到没有break, 无论*str是'+'或是'-',str均会自加 */
case '-': negative = 1;
case '+': ++str;
}
/* 上述操作结束后, 将str前面的空格或是符号位均已跳过.
只跳过一个符号位,若出现"+-2"的情况, 那么当前*str是'-' */
if (!(base & ~0x10)) { /* 0x10的十进制是16, 当base等于16时, 该条件为真;否则为假; */
// 当然,还有可能有其他情况下会进入.比如base=0x******10(*代表任意数);
base += 10; /* default is 10(26). */
if (*str == '0') {
SET_FAIL(++str);
base -= 2; /* Now base is 8 or 16 (24). */
if ((0x20|(*str)) == 'x') { /* WARNING: assumes ascii. */
++str;
base += base; /* Base is 16 (16 or 48). */
}
}
if (base > 16) { /* Adjust in case base wasn't dynamic. */
base = 16;
}
}
number = 0;
if (((unsigned)(base - 2)) < 35) { /* 最大能计算的进制是36进制. */
cutoff_digit = ULONG_MAX % base; // 计算当数值等于临界值时最大还能加上多大的数
cutoff = ULONG_MAX / base; // 计算判断数据溢出的临界值
do {
// 判断每一位的数值; 代码执行类似如下
/* if (((Wuchar)(*str - '0')) <= 9) {
digit = *str - '0';
} else {
if (*str >= 'A') {
// (0x20|(*str)) 将*str的第6位置1.
// 即将所有大写字母的ascii码变为小写字母的ascii码, 而小写字母则不变
// 不清楚的同学可以百度ascii码表, 字母的大小写ascii码只是在二进制的第六位不同.
// 大写字母的二进制第六位是0, 而小写的二进制第六位是1
digit = (((0x20|(*str)) - 'a' + 10));
} else {
digit = 40; // 该位是非法字符.
}
} */
digit = (((Wuchar)(*str - '0')) <= 9)
? (*str - '0')
: ((*str >= 'A')
? (((0x20|(*str)) - 'a' + 10)) /* WARNING: assumes ascii. */
: 40);
// 遇到非法字符, 如16进制, 遇到了'?', 10进制,遇到了'A'
if (digit >= base) {
break;
}
SET_FAIL(++str);
// 判断加上该位的数值后数据溢出
if ((number > cutoff)
|| ((number == cutoff) && (digit > cutoff_digit))) {
number = ULONG_MAX;
negative &= sflag;
SET_ERRNO(ERANGE);
} else { // 未溢出
number = number * base + digit;
}
} while (1);
}
#if _STRTO_ENDPTR
if (endptr) {
*endptr = (Wchar *) fail_char;
}
#endif
{
// ((unsigned long)(-(1+LONG_MIN))) == LONG_MAX, 但不知道为什么要这样获取long的最大值.
// 当欲计算的数为负数时, tmp = LONG_MAX + 1;为正数时, tmp = LONG_MAX
unsigned long tmp = ((negative)
? ((unsigned long)(-(1+LONG_MIN)))+1
: LONG_MAX);
if (sflag && (number > tmp)) {
number = tmp;
SET_ERRNO(ERANGE);
}
}
return negative ? (unsigned long)(-((long)number)) : number;
}
//////////////////////////////////////////////////
isspace(int x)
{
if(x==' '||x=='/t'||x=='/n'||x=='/f'||x=='/b'||x=='/r')
return 1;
else
return 0;
}
isdigit(int x)
{
if(x<='9'&&x>='0')
return 1;
else
return 0;
}
int atoi(const char *nptr)
{
int c; /* current char */
int total; /* current total */
int sign; /* if '-', then negative, otherwise positive */
/* skip whitespace */
while ( isspace((int)(unsigned char)*nptr) )
++nptr;
c = (int)(unsigned char)*nptr++;
sign = c; /* save sign indication */
if (c == '-' || c == '+')
c = (int)(unsigned char)*nptr++; /* skip sign */
total = 0;
while (isdigit(c)) {
total = 10 * total + (c - '0'); /* accumulate digit */
c = (int)(unsigned char)*nptr++; /* get next char */
}
if (sign == '-')
return -total;
else
return total; /* return result, negated if necessary */
}