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

前端 未结 6 625
旧时难觅i
旧时难觅i 2020-12-15 20:07

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 ju

6条回答
  •  臣服心动
    2020-12-15 20:36

    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

提交回复
热议问题