strtoul.c 2.59 KB
/*
=============================================================================
        Copyright (C) 1997-1999 NINTENDO Co.,Ltd.
        
        $RCSfile: strtoul.c,v $
        $Revision: 1.1.1.1 $
        $Date: 2002/10/30 02:07:09 $
=============================================================================
関数名:strtoul
-----------------------------------------------------------------------------
書式:  #include <stdlib.h>
        unsigned long strtoul(const char *string, char **endptr, int base)
引数:  string 変換する文字列
        endptr 認識不能文字列へのポインタ格納先
        base 2〜36で基数。0で string の書式から基数を得る
戻り値:文字列 string を unsigned long 型に変換した値。
説明:  文字列 string を unsigned long 型に変換する。

        文字列 stringは、次の形式で指定する。

        [whitespace][{sign}][{0}][{x | X}][digits]

            <whitespace>    空白類文字 (isspace 参照)
            <sign>          +(-は認識不能文字として扱う)
            <digits>        1桁以上の数値文字

        基数 base に0を指定した場合の基数の扱いは、以下の通り。

        string の最初が '0' で2文字目が 'x' か `X` でなければ8進数
        string の最初が '0' で2文字目が 'x' か 'X' であれば16進数
        string の最初が '1' 〜 '9' であれば10進数

        数字の一部として認識出来ない文字が現れたところで変換を打ち切る。

        endptr が NULL で無いとき、変換を打ち切った文字列へのポインタを
        *endptr にセットする。
-----------------------------------------------------------------------------
*/
#include    "math.h"
#include    "stdlib.h"
#include    "ctype.h"
#include    "string.h"

static  char hexstring[] = {"0123456789abcdefghijklmnopqrstuvwxyz"};

unsigned long strtoul(const char *string, char **endptr, int base)
{
    unsigned long b = 0;
    char    c, *d;

    while(isspace(*string))
      string++;

    if (!*string)   return  0;
    if (*string == '+') string++;
    if (*string == '-') return  0;

    b = 0;
    if (!base)  {
        if (*string == '0') {
            string++;
            if (*string == 'x' || *string == 'X')   {base = 16; string++;}
            else                                    base = 8;
        }   else    base = 10;
    }
    while(*string)  {
        if (!isalnum(*string)) break;
        c = *string++;
        if (c>='A' && c<='Z')   c += 'a' - 'A';
        d = _nstrchr(hexstring, c);
        if (d == NULL)  {string --; break;}
        c = d - &hexstring[0];
        if (c >= base)  {string --; break;}
        if (b > (ULNG_MAX-c)/base)  return  ULNG_MAX;
        b *= base;
        b += c;
    }
    if (endptr != NULL) *endptr = (char *)string;
    return  b;
}