tags:

views:

841

answers:

4

I don't understand the results of the following C code.

main()
{
   char s[] = "AAA";
   advanceString(s);
}

void advanceString(p[3])
{
     int val = atoi(p);
     printf("The atoi val is %d\n",val);
}

Here the atoi val is shown as 0. But I could not figure out the exact reason. As per my understanding, it should be the summation of decimal equivalent of each values in the array.? Please correct me if I am wrong.

+10  A: 

It tries to convert the string into an integer. Since AAA cannot be converted into an integer the value is 0. Try giving it 42 or something.

If no valid conversion could be performed, a zero value is returned.

See http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

Snake
+25  A: 

atoi() converts a string representation of an integer into its value. For instance:

int main(void)
{
     const char *string="12345";

     printf("The value of %s is %d\n", string, atoi(string));

     return 0;
}

Now that you know what it does, please don't use it. atoi() does no error checking whatsoever, which makes anything relying on it to convert arbitrary input fragile, at best. Instead, use strtol() (POSIX centric example):

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main(void)
{
        static const char *input ="123abc";
        char *garbage = NULL;
        long value = 0;

        errno = 0;

        value = strtol(input, &garbage, 0);

        switch (errno) {
        case ERANGE:
                printf("The data could not be represented.\n");
                return 1;
        case EINVAL:
                printf("Unsupported base / radix.\n");
                return 1;
        }

        printf("The value is %ld, leftover garbage in the string is %s\n",
            value, garbage == NULL ? "N/A" : garbage);

        return 0;
}

When run, this gives:

The value is 123, leftover garbage in the string is abc

If you don't care about saving / examining the garbage, you can set the second argument to NULL. There is no need to free(garbage). Also note, if you pass 0 as the third argument, its assumed the input is the desired value of a decimal, hex or octal representation. If you need a radix of 10, use 10 - it will fail if the input is not as you expect.

You'd also check the return value for the maximum and minimum value a long int can handle. However, if either are returned to indicate an error, errno is set. An exercise for the reader is to change *input from 123abc to abc123.

Its important to check the return, as your example shows what happens if you don't. AbcDeFg is not a string representation of an integer, and you need to deal with that in your function.

Tim Post
You can use the [strerror](http://en.wikipedia.org/wiki/Strerror) to get a human readable text from an error code.
Tarantula
+1  A: 

read atoi() as a to i (ascii to integer)

atoi() converts a string representing a decimal number, to integer.

char s[] = "42";
int num = atoi(s);//num has value 42 
Deep
+1 because it contains everything an answer needs ;-)
frunsi
+2  A: 

atoi expects its argument to a be string representation of a decimal (base-10) integer constant; AAA is not a valid decimal integer constant, so atoi returns 0 because it has no other way to indicate that the input is invalid.

Note that atoi will convert up to the first character that isn't part of a valid integer constant; IOW, "123" and "123w" will both be converted to 123.

Like everyone else is saying, don't use atoi; use strtol instead.

John Bode