面试常考题目之atoi的实现

题目:

编程实现atoi函数。

分析:

要实现string转int,直接每一次读入一个字符,然后减去'0',即可自动转换成int数值;如果有多位,则当前位乘以10,加上当前位的int数值。

当然,这个题目不只是考察这个转换过程,溢出判断是另外一个重点。

下面的代码是atoi.c的内容:

/*---------------------------------------------------------------------------
*   filename   -   atol.c
*
*   function(s)
*                 atol     -   converts   a   string   to   a   long
*                 atoi     -   converts   a   string   to   an   int
*                 _wtol     -   converts   a   wide-character   string   to   a   long
*                 _wtoi     -   converts   a   wide-character   string   to   an   int
*--------------------------------------------------------------------------*/

/*
*             C/C++   Run   Time   Library   -   Version   11.0
*
*             Copyright   (c)   1987,   2002   by   Borland   Software   Corporation
*             All   Rights   Reserved.
*
*/

/*   $Revision:   9.4.2.1   $                 */

#include   <stdlib.h>
#include   <ctype.h>
#include   <tchar.h>

#undef       atoi                       /*   macro   in   stdlib   */

/*--------------------------------------------------------------------------*

Name                         atol,   _wtol   -   converts   a   string   to   an   integer

Usage                       long   atol(const   char   *nptr);
                                long   _wtol(const   wchar_t   *nptr);

Prototype   in         stdlib.h

Description           Convert   a   string   to   a   long   integer.     The   syntax   of
                                the   string   must   be:

                                                long           ::=   [isspace]*   [sign]   digit   [digit]*

                                Only   decimal   integers   are   acceptable.

                                Error   handling   is   poor.     The   function   will   protect
                                itself   (crash-proof)   but   there   is   no   defined   method
                                to   return   an   error   indication   to   the   caller.     The
                                result   is   undefined   if   the   input   string   is   invalid.

Return   value         converted   long   value   of   the   input   string.     If   the   string
                                cannot   be   converted   to   a   long,   the   return   value   is   0.

*---------------------------------------------------------------------------*/

long   _RTLENTRY   _EXPFUNC   _ttol(const   _TCHAR   *strP)
{
        _TCHAR   c;
        int     is_neg;
        long   result;

        result   =   0;                                           /*   default   result   is   0   */

        while   (_istspace((c   =   *strP++)))     /*   skip   any   whitespace   characters   */
                ;

        if   (c   ==   _TEXT('+')   ||   c   ==   _TEXT('-'))               /*   remember   if   negative   sign   seen   */
        {
                is_neg   =   c   ==   _TEXT('-');
                c   =   *strP++;                                 /*   skip   sign,   get   next   char   */
        }
        else
                is_neg   =   0;

        while   (c   >=   _TEXT('0')   &&   c   <=   _TEXT('9'))         /*   accumulate   digits,   ignore   overflow   */
        {
                result   =   result   *   10   +   c   -   _TEXT('0');
                c   =   *strP++;
        }

        return   (is_neg   ?   -result   :   result);   /*   negate   result   if   '-'   seen   */
}

/*--------------------------------------------------------------------------*

Name                         atoi,   _wtoi   -   converts   a   string   to   an   integer

Usage                       int   atoi(char   *nptr);
                                int   atoi(wchar_t   *nptr);

Prototype   in         stdlib.h

Description           Convert   ASCII   string   to   word   integer.

                                The   only   difference   between   this   and   the   atol
                                function   is   whether   the   result   is   truncated.

Return   value         converted   long   value   of   the   input   string.     If   the   string
                                cannot   be   converted   to   an   int,   the   return   value   is   0.

*---------------------------------------------------------------------------*/

int   _RTLENTRY   _EXPFUNC   _ttoi(const   _TCHAR   *strP)
{
                return   (int)   _ttol   (strP);
}


#ifndef   _UNICODE
#define   _tchartodigit(c)         ((c)   >=   '0'   &&   (c)   <=   '9'   ?   (c)   -   '0'   :   -1)
#else     /*   _UNICODE   */
int   _wchartodigit(wchar_t);
#define   _tchartodigit(c)         _wchartodigit((wchar_t)(c))
#endif     /*   _UNICODE   */

/***
*long   atol(char   *nptr)   -   Convert   string   to   long
*
*Purpose:
*               Converts   ASCII   string   pointed   to   by   nptr   to   binary.
*               Overflow   is   not   detected.
*
*Entry:
*               nptr   =   ptr   to   string   to   convert
*
*Exit:
*               return   long   int   value   of   the   string
*
*Exceptions:
*               None   -   overflow   is   not   detected.
*
*******************************************************************************/

long   __cdecl   _tstol(
                const   _TCHAR   *nptr
                )
{
                int   c;                             /*   current   char   */
                long   total;                   /*   current   total   */
                int   sign;                       /*   if   '-',   then   negative,   otherwise   positive   */
#if   defined   (_MT)   &&   !defined   (_UNICODE)
                pthreadlocinfo   ptloci   =   _getptd()->ptlocinfo;

                if   (   ptloci   !=   __ptlocinfo   )
                        ptloci   =   __updatetlocinfo();

                /*   skip   whitespace   */
                while   (   __isspace_mt(ptloci,   (int)(_TUCHAR)*nptr)   )
#else     /*   defined   (_MT)   &&   !defined   (_UNICODE)   */
                while   (   _istspace((int)(_TUCHAR)*nptr)   )
#endif     /*   defined   (_MT)   &&   !defined   (_UNICODE)   */
                        ++nptr;

                c   =   (int)(_TUCHAR)*nptr++;
                sign   =   c;                       /*   save   sign   indication   */
                if   (c   ==   _T('-')   ||   c   ==   _T('+'))
                        c   =   (int)(_TUCHAR)*nptr++;         /*   skip   sign   */

                total   =   0;

                while   (   (c   =   _tchartodigit(c))   !=   -1   )   {
                        total   =   10   *   total   +   c;           /*   accumulate   digit   */
                        c   =   (_TUCHAR)*nptr++;         /*   get   next   char   */
                }

                if   (sign   ==   '-')
                        return   -total;
                else
                        return   total;       /*   return   result,   negated   if   necessary   */
}


/***
*int   atoi(char   *nptr)   -   Convert   string   to   long
*
*Purpose:
*               Converts   ASCII   string   pointed   to   by   nptr   to   binary.
*               Overflow   is   not   detected.     Because   of   this,   we   can   just   use
*               atol().
*
*Entry:
*               nptr   =   ptr   to   string   to   convert
*
*Exit:
*               return   int   value   of   the   string
*
*Exceptions:
*               None   -   overflow   is   not   detected.
*
*******************************************************************************/

int   __cdecl   _tstoi(
                const   _TCHAR   *nptr
                )
{
                return   (int)_tstol(nptr);
}

#ifndef   _NO_INT64

__int64   __cdecl   _tstoi64(
                const   _TCHAR   *nptr
                )
{
                int   c;                             /*   current   char   */
                __int64   total;             /*   current   total   */
                int   sign;                       /*   if   '-',   then   negative,   otherwise   positive   */
#if   defined   (_MT)   &&   !defined   (_UNICODE)
                pthreadlocinfo   ptloci   =   _getptd()->ptlocinfo;

                if   (   ptloci   !=   __ptlocinfo   )
                        ptloci   =   __updatetlocinfo();

                /*   skip   whitespace   */
                while   (   __isspace_mt(ptloci,   (int)(_TUCHAR)*nptr)   )
#else     /*   defined   (_MT)   &&   !defined   (_UNICODE)   */
                while   (   _istspace((int)(_TUCHAR)*nptr)   )
#endif     /*   defined   (_MT)   &&   !defined   (_UNICODE)   */
                        ++nptr;

                c   =   (int)(_TUCHAR)*nptr++;
                sign   =   c;                       /*   save   sign   indication   */
                if   (c   ==   _T('-')   ||   c   ==   _T('+'))
                        c   =   (int)(_TUCHAR)*nptr++;         /*   skip   sign   */

                total   =   0;

                while   (   (c   =   _tchartodigit(c))   !=   -1   )   {
                        total   =   10   *   total   +   c;           /*   accumulate   digit   */
                        c   =   (_TUCHAR)*nptr++;         /*   get   next   char   */
                }

                if   (sign   ==   _T('-'))
                        return   -total;
                else
                        return   total;       /*   return   result,   negated   if   necessary   */
}


可以看出,程序需要完成以下几个步骤:

1. 判空;

2.去空格;

3. 判断符号;

4. 数值转换;

5. 返回有符号数。

因此,实现代码如下。

代码:

#include <stdio.h>

int myatoi(const char* str)
{
    if (str == NULL) return 0;

    int slen = strlen(str);
    if(slen < 0) return 0;
    char* c = str;

    int ret = 0,sign=1;
    while(*c == ' ') c++;
    if(*c == '+')
    {
        sign = 1;
        c++;
    }
    else if(*c == '-')
    {
         sign = -1;
         c++;
    }

    int t = 0;
    while((*c >='0')&&(*c <= '9'))
    {
        t = *c-'0';
        ret = ret *10+t;
        c++;
    }
    return ret * sign;
}

int main()
{
    printf("%d\n",myatoi("124"));
    printf("%d\n",myatoi("+124"));
    printf("%d\n",myatoi("-124"));
    printf("%d\n",myatoi("    124"));
    printf("%d\n",myatoi("     +124"));
    printf("%d\n",myatoi("      -124"));

    printf("%d\n",myatoi(NULL));
    printf("%d\n",myatoi("1d24"));
    printf("%d\n",myatoi(""));

    return 0;
}


当然,由于笔者对于溢出判断的理解比较浅薄,如果有更好的建议,请不吝指正~

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2012-05-07 11:31  wangicter的博客  阅读(237)  评论(0编辑  收藏  举报