atoi return error

This is a discussion on atoi return error within the C Programming forums, part of the General Programming Boards category; ok, i've got one for ya! i've just looked at a refernce for the atoi function in stdlib.h. it states ...

  1. #1
    Registered User
    Join Date
    Aug 2002
    Posts
    351

    atoi return error

    ok, i've got one for ya!

    i've just looked at a refernce for the atoi function in stdlib.h.

    it states that atoi returns a 0 if it cannot convert the char*.

    how, then, is "0" supposed to be converted with confirmation?

    therefore, aoti cannot be used to check for a valid int in a character array. is the best way to achieve this to convert to ascii and test for the int range for each char in the array?

    or is there a function that can do this?

    TIA, rotis23

  2. #2
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    You could check every character in the string if it's a number:
    Code:
    #define FirstDigit 48
    
    bool IsNumeric(char* String)
    {
       bool Result = true;
       for(int i=0; i<strlen(String); i++)
       {
          if((String[i] < FirstDigit) || (String[i] > FirstDigit + 9)) Result = false;
       }
       return Result;
    }
    (There might be a standard function doing this already)
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  3. #3
    Me want cookie! Monster's Avatar
    Join Date
    Dec 2001
    Posts
    680
    Or just use the isdigit function...
    Code:
    #include <ctype.h>
    
    bool IsNumeric(char* String)
    {
       char *ptr = String;
    
       while(*ptr && isdigit(*ptr))
          ptr++;
    
       return (*ptr ? false : true);
    }

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    Use strtol instead of atoi. One way to think of atoi might be as follows.
    Code:
    int atoi(const char *s)
    {
        return (int)strtol(s, NULL, 10);
    }
    So if you want the error detection, use strtol but do error handling using the second parameter instead of passing it NULL.

  5. #5
    Registered User
    Join Date
    Aug 2002
    Posts
    351
    i think i might just check manually - using an ascii range.

    aswell as atoi, strtol returns a 0 if an error occurs. i presume the second parameter will not point to NULL if it finds a non-numerical char. hence, the error check.

    is isdigit part of standard c?

    thanks guys.

  6. #6
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    rotis23>is isdigit part of standard c?
    Yes.

    rotis23>i think i might just check manually - using an ascii range

    FWIW I have a few comments.

    Checking the digits first may work fine. But consider that you will be doing the checking up front, and if the string contains only digits it sounds as if you will use atoi. It is quite possible that atoi itself calls strtol, which performs another check on the validity as it attempts to convert the data (but its error-checking results are thrown away). If performance is an issue, this double-checking may be a problem. My suggestion was that since you want error checking and strtol does this, maybe you could use it.
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    int myatoi(const char *s, int *value)
    {
        if ( s != NULL && *s != '\0' && value != NULL )
        {
            char *endptr = s;
            *value = (int)strtol(s, &endptr, 10);
            if ( *endptr == '\0' )
            {
                return 1;
            }
        }
        return 0; /* failed to convert string to integer */
    }
    
    int main(void)
    {
        int i, value = 2;
        const char *text[] =
        {
            "0", "0x0", "0.0", "00", "15", "", NULL, "a", " 0", "-0", " +0",
        };
        for ( i = 0; i < sizeof(text)/sizeof(*text); ++i )
        {
            int result = myatoi(text[i], &value);
            printf("text[%d] = \"%s\", value = %d (%s)\n", i,
                   text[i] ? text[i] : "<NULL>", value,
                   result ? "confirmed" : "error");
        }
        return 0;
    }
    
    /* my output
    text[0] = "0", value = 0 (confirmed)
    text[1] = "0x0", value = 0 (error)
    text[2] = "0.0", value = 0 (error)
    text[3] = "00", value = 0 (confirmed)
    text[4] = "15", value = 15 (confirmed)
    text[5] = "", value = 15 (error)
    text[6] = "<NULL>", value = 15 (error)
    text[7] = "a", value = 0 (error)
    text[8] = " 0", value = 0 (confirmed)
    text[9] = "-0", value = 0 (confirmed)
    text[10] = " +0", value = 0 (confirmed)
    */
    Some of these results may not be what you want, so first checking for all digits may be necessary. But if the behavior of strtol is what you need, then you could skip the double-checking.

    <nitpicks>
    Magos>#define FirstDigit 48
    This is less portable than #define FirstDigit '0'.

    Monster,Magos>bool, true, false
    C++, not C.
    </nitpicks>

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Beginner Needs help in Dev-C++
    By Korrupt Lawz in forum C++ Programming
    Replies: 20
    Last Post: 09-28-2010, 01:17 AM
  2. error: template with C linkage
    By michaels-r in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2006, 08:11 AM
  3. Alegro closes out on me
    By campsoup1988 in forum C++ Programming
    Replies: 8
    Last Post: 04-03-2006, 10:40 AM
  4. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  5. Learning OpenGL
    By HQSneaker in forum C++ Programming
    Replies: 7
    Last Post: 08-06-2004, 08:57 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21