字符串和整数之间互相转换

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

value: 要转换的整数
string: 转换后的字符串
radix: 转换进制数,如2,8,10,16 进制等。

example of itoa

#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

str 要转换为整数的字符串。
返回值
该函数返回转换后的长整数,如果没有执行有效的转换,则返回零。

example of atoi
#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 */
}
 

发布了188 篇原创文章 · 获赞 65 · 访问量 8388

猜你喜欢

转载自blog.csdn.net/qq_43808700/article/details/104398762