Cにおける数字文字列回転doubleとintの実現原理

5715 ワード

Cでは、数値文字列はchar[]として定義されます.
関連apiは「c++中数字とstring変換」を参照
 
①共通関数
 
#include
atoi---回転int
atod---回転double
strtod---回転double
strtol---回転long
 
四兄弟の仕事の原理は似たような言語で説明できます.
        nptr   ,          ,                 ,             ('\0')    。

空白を取り除き、正負を残し、数字を残す.
 
4人の兄弟の中で、strtodとstrtol双子の特殊なところは:
これらのパラメータには2つのポインタが含まれており、2番目のポインタはスキャンが終了した位置のポインタを返します.
int atoi(const char *nptr);
double atof(const char *nptr);

long int strtol(const char *nptr,char **endptr,int base);
double strtod(const char *nptr,char **endptr);

 
②実現原理
2.1 atoi
int Atoi(const char *pstr)
{
    int sign = 1;
    int num = 0;

    while (*pstr == ' ' || *pstr == '\t') //   '/t'  
    {
        pstr++;
    }

    if (*pstr == '-')
    {
        sign = -1;
        pstr++;
    }

    while (*pstr)
    {
        if (*pstr >= '0' && *pstr <= '9')
        {
            num = 10 * num + *pstr - '0';
        }
        else
        {
            return num * sign;
        }
        pstr++;
    }
    return (num * sign);
}

 
2.2 atof
 
double Atof(const char *pstr)
{
    double sign = 1.0;
    double num1 = 0.0;
    double num2 = 0.0;
    double point = 0.1;

    while (*pstr == ' ' || *pstr == '/t')
    {
        pstr++;
    }

    if (*pstr == '-')
    {
        sign = -1;
        pstr++;
    }

    while (*pstr)
    {
        if (*pstr == '.')
        {
            pstr++;
            while (*pstr >= '0' && *pstr <= '9')
            {
                num1 += point * (*pstr - '0');
                point *= 0.1;
                pstr++;
            }
        }
        else if (*pstr >= '0' && *pstr <= '9')
        {
            num2 = num2 * 10 + *pstr -'0';
        }
        else
        {
            return (num1 + num2) * (sign);
        }
        pstr++;
    }
    return (num1 + num2) * (sign);
}

 
2.3 strtol
#define TOLOWER(x) ((x) | 0x20)  
#define isxdigit(c)    (('0' <= (c) && (c) <= '9') /  
             || ('a' <= (c) && (c) <= 'f') /  
             || ('A' <= (c) && (c) <= 'F'))  
  
#define isdigit(c)    ('0' <= (c) && (c) <= '9')  
  
unsigned long strtoul(const char *cp,char **endp,unsigned int base)  
{  
    unsigned long result = 0,value;  
  
    if (!base) {  
        base = 10;  
        if (*cp == '0') {  
            base = 8;  
            cp++;  
            if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) {  
                cp++;  
                base = 16;  
            }  
        }  
    } else if (base == 16) {  
        if (cp[0] == '0' && TOLOWER(cp[1]) == 'x')  
            cp += 2;  
    }  
    while (isxdigit(*cp) &&  
           (value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {  
        result = result*base + value;  
        cp++;  
    }  
    if (endp)  
        *endp = (char *)cp;  
    return result;  
}  
long strtol(const char *cp,char **endp,unsigned int base)  
{  
    if(*cp=='-')  
        return -strtoul(cp+1,endp,base);  
    return strtoul(cp,endp,base);  
}  

 
2.4 strtod
 
double Strtod(char *str, char **endstr){
    double num1 = 0.0;
    double num2 = 0.0;
    double point = 0.1;
    int sign = 1;

    int len = strlen(str) + 1;
    *endstr = new char[len];
    memset(*endstr, 0, len);

    if (*str == '-')
    {
        sign = -1;
        ++str;
    }

    if (!isdigit(*str))
    {
        strcpy(*endstr, str);
        return 0.0;
    }
    while (*str && isdigit(*str))
    {
        if (*str == '.')
        {
            ++str;
            while (*str && isdigit(*str))
            {
                num2 += point * ((*str) - '0');
                point *= 0.1;
                ++str;
            }
            strcpy(*endstr, str);
            break;
        }
        else
        {
            num1 = 10 * num1 + *str - '0';
            str++;
            if (!*str || !isdigit(*str))
            {
                strcpy(*endstr, str);
                break;
            }
        }
    }
    
    return (num1 + num2) * sign;
}
{
    double num1 = 0.0;
    double num2 = 0.0;
    double point = 0.1;
    int sign = 1;

    int len = strlen(str) + 1;
    *endstr = new char[len];
    memset(*endstr, 0, len);

    if (*str == '-')
    {
        sign = -1;
        ++str;
    }

    if (!isdigit(*str))
    {
        strcpy(*endstr, str);
        return 0.0;
    }
    while (*str && isdigit(*str))
    {
        if (*str == '.')
        {
            ++str;
            while (*str && isdigit(*str))
            {
                num2 += point * ((*str) - '0');
                point *= 0.1;
                ++str;
            }
            strcpy(*endstr, str);
            break;
        }
        else
        {
            num1 = 10 * num1 + *str - '0';
            str++;
            if (!*str || !isdigit(*str))
            {
                strcpy(*endstr, str);
                break;
            }
        }
    }
    
    return (num1 + num2) * sign;
}

 
 
 
 
以下の文章を参考にして、ソースコードの一部のエラーを修正しました.
atoi atofソースコード
strtoul,strtol実装コード