题目:
编程实现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;
}
当然,由于笔者对于溢出判断的理解比较浅薄,如果有更好的建议,请不吝指正~