美文网首页
int atoi(const char* str)

int atoi(const char* str)

作者: yuansip | 来源:发表于2016-11-15 10:59 被阅读0次

    自己在实现字符串转整数时,要注意一下几个要点:

    1. 正负号的处理
    2. 非数字字符的处理
    3. 溢出的处理 (难点)

    下面给出一个实现(转自Nut/OS: c/stdlib/strtol.c)

    /*
     * Copyright (C) 2004 by egnite Software GmbH. All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * 1. Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     * 2. Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     * 3. Neither the name of the copyright holders nor the names of
     *    contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
     * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
     * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
     * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     * SUCH DAMAGE.
     *
     * For additional information see http://www.ethernut.de/
     *
     *-
     * Copyright (c) 1990 The Regents of the University of California.
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     * 1. Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     * 2. Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     * 3. Neither the name of the University nor the names of its contributors
     *    may be used to endorse or promote products derived from this software
     *    without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     * SUCH DAMAGE.
     */
    
    /*
     * $Log$
     * Revision 1.4  2008/02/15 17:13:01  haraldkipp
     * Use configurable constant attribute.
     *
     * Revision 1.3  2006/10/08 16:48:08  haraldkipp
     * Documentation fixed
     *
     * Revision 1.2  2005/08/02 17:46:47  haraldkipp
     * Major API documentation update.
     *
     * Revision 1.1  2004/09/08 10:23:35  haraldkipp
     * Generic C stdlib added
     *
     */
    
    #include <compiler.h>
    #include <ctype.h>
    #include <errno.h>
    #include <limits.h>
    #include <stdlib.h>
    
    
    long strtol(CONST char *nptr, char **endptr, int base)
    {
        register CONST char *s;
        register long acc, cutoff;
        register int c;
        register int neg, any, cutlim;
    
        /*
         * Skip white space and pick up leading +/- sign if any.
         * If base is 0, allow 0x for hex and 0 for octal, else
         * assume decimal; if base is already 16, allow 0x.
         */
        s = nptr;
        do {
            c = (unsigned char) *s++;
        } while (isspace(c));
        if (c == '-') {
            neg = 1;
            c = *s++;
        } else {
            neg = 0;
            if (c == '+')
                c = *s++;
        }
        if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) {
            c = s[1];
            s += 2;
            base = 16;
        }
        if (base == 0)
            base = c == '0' ? 8 : 10;
    
        /*
         * Compute the cutoff value between legal numbers and illegal
         * numbers.  That is the largest legal value, divided by the
         * base.  An input number that is greater than this value, if
         * followed by a legal input character, is too big.  One that
         * is equal to this value may be valid or not; the limit
         * between valid and invalid numbers is then based on the last
         * digit.  For instance, if the range for longs is
         * [-2147483648..2147483647] and the input base is 10,
         * cutoff will be set to 214748364 and cutlim to either
         * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
         * a value > 214748364, or equal but the next digit is > 7 (or 8),
         * the number is too big, and we will return a range error.
         *
         * Set any if any `digits' consumed; make it negative to indicate
         * overflow.
         */
        cutoff = neg ? LONG_MIN : LONG_MAX;
        cutlim = cutoff % base;
        cutoff /= base;
        if (neg) {
            if (cutlim > 0) {
                cutlim -= base;
                cutoff += 1;
            }
            cutlim = -cutlim;
        }
        for (acc = 0, any = 0;; c = (unsigned char) *s++) {
            if (isdigit(c))
                c -= '0';
            else if (isalpha(c))
                c -= isupper(c) ? 'A' - 10 : 'a' - 10;
            else
                break;
            if (c >= base)
                break;
            if (any < 0)
                continue;
            if (neg) {
                if ((acc < cutoff || acc == cutoff) && c > cutlim) {
                    any = -1;
                    acc = LONG_MIN;
                    errno = ERANGE;
                } else {
                    any = 1;
                    acc *= base;
                    acc -= c;
                }
            } else {
                if ((acc > cutoff || acc == cutoff) && c > cutlim) {
                    any = -1;
                    acc = LONG_MAX;
                    errno = ERANGE;
                } else {
                    any = 1;
                    acc *= base;
                    acc += c;
                }
            }
        }
        if (endptr != 0)
            *endptr = (char *) (any ? s - 1 : nptr);
        return (acc);
    }
    
    

    相关文章

      网友评论

          本文标题:int atoi(const char* str)

          本文链接:https://www.haomeiwen.com/subject/mmikpttx.html