C/C++校招笔试面试经典题目总结七

题目71:实现strtol函数,其原型如为unsigned int strtoul(const char *cp, char **endp, unsigned int base),num_str存放待转换的字符串,可以是负数也可以是正数;endptr指向第一个非法字符的地址,如果endptr为null则不指向第一个非法字符的地址;base用于指示进制,若base为0,则根据num_str的指示来转换。函数必须检查溢出,如果正数溢出,返回int_max;若负数溢出,返回int_min。

解析:这道题目是迅雷C++笔试的编程大题,与atoi函数的实现又稍有区别。atoi函数的实现有如下要点:(1)检查非法输入;(2)检查溢出;实现如下:
#include "stdafx.h"
#include 
#include 

long long StrToIntCore(const char* str, bool minus);

enum Status {kValid = 0, kInvalid};//设置全局变量,空字符''和‘0’都返回的0,但前者设置全局变量的值与后者加以区分
int g_nStatus = kValid;

int StrToInt(const char* str)
{
    g_nStatus = kInvalid;
    long long num = 0;

    if(str != NULL && *str != '\0') 
    {
        bool minus = false;
        if(*str == '+')//符号判断
            str ++;
        else if(*str == '-') 
        {
            str ++;
            minus = true;
        }

        if(*str != '\0') 
        {
            num = StrToIntCore(str, minus);
        }
    }

    return (int)num;
}

long long StrToIntCore(const char* digit, bool minus)
{
    long long num = 0;

    while(*digit != '\0') 
    {
        if(*digit >= '0' && *digit <= '9') 
        {
            int flag = minus ? -1 : 1;
            num = num * 10 + flag * (*digit - '0');

            if((!minus && num > 0x7FFFFFFF) 
                || (minus && num < (signed int)0x80000000))//溢出检查
            {
                num = 0;
                break;
            }

            digit++;
        }
        else 
        {
            num = 0;
            break;
        }
    }

    if(*digit == '\0') 
    {
        g_nStatus = kValid;
    }

    return num;
}
然而迅雷的这道编程题,与上边的又有些许区别,加入了进制的考查。
#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);  
}  
    INT32S  atoi(const     INT8S  *nptr)//  
{  
    return  strtol(nptr, (    INT8S  **)NULL, 10);  
} 

明天继续更新,去吃饭喽..


你可能感兴趣的:(C++)