Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does atoi() function in C++ work?

Tags:

c++

So...I know that the atoi function in the C++ standard library is supposed to convert a string into an integer...how does it work?...(I'm trying to learn stuff and I was just wondering)...if you could show me the code from it or make your own that would do the same task it'd be greatly appreciated...thanks in advance.

like image 230
JacKeown Avatar asked Apr 18 '11 23:04

JacKeown


People also ask

What does atoi return in C?

The atoi() function in C takes a string (which represents an integer) as an argument and returns its value of type int. So basically the function is used to convert a string argument to an integer.

Where is atoi defined in C?

The atoi() function in C++ is defined in the cstdlib header. It accepts a string parameter that contains integer values and converts the passed string to an integer value.

What can I use instead of atoi in C?

So you can replace atoi() with strtol(nptr, NULL, 10) everywhere. As for improving error checking, see the documentation of strtol and what it returns upon different errors. @user3521585 Instead of TempS = atoi(TempStorage); , write TempS = strtol (TempStorage, NULL, 10); and that's guaranteed to be equivalent.

Is atoi safe in C?

* The atoi function is not thread-safe and also not async-cancel safe. * The atoi function has been deprecated by strtol and should not be used in new code. Save this answer.


2 Answers

Something like this:

int atoi( const char *c ) {
    int value = 0;
    int sign = 1;
    if( *c == '+' || *c == '-' ) {
       if( *c == '-' ) sign = -1;
       c++;
    }
    while ( isdigit( *c ) ) {
        value *= 10;
        value += (int) (*c-'0');
        c++;
    }
    return value * sign;
}

You loop through the characters in the string as long as they are digits. For each one, add to the counter you're keeping - the value to add is the integer value of the character. This is done by subtracting the ascii value of '0' from the ascii value of the digit in question.

Note that this code doesn't handle overflow. If you pass in "887452834572834928347578423485273" (which won't fit in an int), the result is undefined.

like image 74
Graeme Perrow Avatar answered Nov 04 '22 16:11

Graeme Perrow


Digit by digit:

A char *, strictly speaking, is a pointer to a char. A pointer is just an address to some place in memory. In C/C++ (and Java), strings are made up of characters that can, individually, be treated as integers (usually one byte), thanks to ASCII.

In C (and C++), a pointer to an item of some type is the same as a pointer to an array of elements of that type. Strings in pure C are just arrays of chars, with a '\0' (NUL) at the end so that you know when you've hit the end of a string without having to pass around its length everywhere (a pointer is only an address, it knows nothing about what it points to).

Ignore the const keywords for now.

The C version of atoi loops through each character in the string. The *str++ does several things (it's important to understand how it works, but it's a horrible way to actually write C). It's equivalent to *(str++). The str++ returns the value of str (a pointer) and then increments it by one (but it returns the old value!). The * "dereferences" the pointer, basically reading in a char from memory. This char is stored in digit and then compared to NUL. Characters are stored in ASCII, which represents digits contiguously, so we can just check that digit is between 0 and 9. We know now that we're reading in a new digit, so we multiply the previous value by 10 to "shift" the value over and then add in the digit.

Pure C version:

int atoi(const char* str) {
  int num = 0;
  char digit;
  while ((digit = *str++) != '\0') {
    if (digit < '0' || digit > '9') {
      return num;  /* No valid conversion possible */
    }
    num *= 10;
    num += c - '0';
  }
  return num;
}

A C++ string is an object to make dealing with strings easier. You can get a char * from a C++ string with .c_str().

C++ version (more likely an inlined call to the char* version with "return atoi(str.c_str());"):

int atoi(const std::string& str) {
  int n = 0;
  for (int i = 0; i < str.size(); i += 1) {
    char digit = str.at(i);   /* Could probably use iterator here,
                               * but this is more explicit. */
    if (digit < '0' || digit > '9') {
      return n;  /* No valid conversion possible. */
    }
    n *= 10;
    n += digit - '0';
  }
  return n;
}

Edit: Fixed issue where <> would not display properly.

Edit: C++ string version added

Edit: Fixed so it returns 123 in 123a case.

Edit: Changed stray num to n in C++ version

like image 42
Hoa Long Tam Avatar answered Nov 04 '22 15:11

Hoa Long Tam