-2

So I want to take a string in such as 8302 and convert this into an integer by creating my own function and not using the stoi/atoi functions.

I tried so far by doing:

int stringToInt(string input)
{
    int i = 0;
    while(input[i] >= '0' && input[i] <= '9')
    {
        input[i] = input[i] * 10 + ......
        i++;
    }
return i;
}

I know i need to keep multiplying by 10 everytime i find an integer so i can increase it e.g 123 = 1*10*10+2*10+3. but i dont know how to code this. could anyone suggest a method?

Jay
  • 19,649
  • 38
  • 121
  • 184
Ray Chen
  • 23
  • 1
  • 6

6 Answers6

2

It might be easiest to do it in a recursive manner. Use the following idea:

8302 = 830 * 10 + 2

That is:

  1. If there is only one char in the string - return it; otherwise continue
  2. Separate the last char in the string
  3. Convert the string (without the last char) to integer - using recursion
  4. Multiply by 10 and add the last char

There are a lot of details here:

  • how to convert 1 char to an integer? - subtract '0' from it
  • how to separate a char from the rest of the string? - use substr
  • when you have a working recursive solution, you might want to convert it to an iterative solution - this will make it faster, but maybe less readable
  • what to do with invalid strings like "aaa" or "123haha" - my algorithm doesn't handle that
anatolyg
  • 26,506
  • 9
  • 60
  • 134
  • Other points the OP should consider: a. Handling negative numbers. b. What to do if step 4 would overflow his accumulator (and there are some interesting questions about how to detect that without triggering overflow). c. Combining the last two: handling entry of the most negative number without triggering overflow. – Martin Bonner supports Monica Sep 27 '16 at 12:53
  • I think these considerations are mostly for other people who may read this in future; OP mentioned "stoi/atoi" so he doesn't seem to care about such things, just like [`atoi` doesn't care](http://stackoverflow.com/q/20583945/509868) – anatolyg Sep 27 '16 at 12:59
1

Before you could define a char2int conversion:

inline int ctoi(char c) {
  switch (c) {
    case '0':
      return 0;
    case '1':
      return 1;
    case '2':
      return 2;
    case '3':
      return 3;
    case '4':
      return 4;
    case '5':
      return 5;
    case '6':
      return 6;
    case '7':
      return 7;
    case '8':
      return 8;
    case '9':
      return 9;
    default:
      throw std::runtime_error("Invalid char conversion");
  }
}

And use it:

int my_stoi_dec(const std::string& str) {
  int rtn = 0;
  int exp = 1;
  for (auto cp = str.crbegin(); cp != str.crend(); ++cp) {
    char c = *cp;
    if (isdigit(c)) {
      rtn +=  ctoi(c) * exp;
      exp *= 10;
    } else if (c == '+') {
      return rtn;
    } else if (c == '-') {
      return rtn * -1;
    } else {
      throw std::runtime_error("Integer error conversion");
    }
  }
}
BiagioF
  • 9,368
  • 2
  • 26
  • 50
-1

This one is very close to your attempt:

int toInt(const std::string& input)
{
  int i = 0;
  for (const auto c : input)
  {
    if (c < '0' || c > '9')
      break;
    i = i*10 + c-'0';
  }
  return i;
}

The only assumption is that the characters '0' to '9' lie directly next to each other in the character set. The if statement makes sure that we stop at non-digit characters. The digit-characters are converted to their integer value using c-'0'.

Please keep in mind that this only parses the first digits of a string. Strings that start with a sign + or - are not considered.

pschill
  • 5,055
  • 1
  • 21
  • 42
  • This is about as clean as it can get. You should add explanations on your answer, because it seems most suitable for using as-is. – anatolyg Sep 27 '16 at 13:01
-1

A good way is to find your first digit and go from there make a multiplayer variable and multiply it by ten every digit. for every char you add you have to subtract '0' from it as '0' is not equal to int 0.

example:

 string s = "12346";
 int multiplayer = 1;
 int i = 0;

 int result = 0;

 while (s[i] >= '0' && s[i] <= '9')
 ++i;

--i;
for(i ; i >= 0 ; --i){
   result += (s[i] - '0') * multiplayer;
   multiplayer *= 10;
 }
user3196144
  • 197
  • 2
  • 11
-2

It is much better that you start your conversion from right to left.

So you will iterate your string starting from its end, and ending on its beginning. On each iteration, we will take the character, convert it to int and multiply it with its multiplier (its position in the result integer) and then add it to the final result.

This should work:

#include <iostream>
#include <string>

int stringToInt(std::string input)
{
    int result = 0;
    int multiplier = 1;

    for (int i = input.length() - 1; i >= 0; i--) // start from right
    {
        if (input[i] - '0' < 0 || input[i] - '0' > 9) // if any character is not an integer, return maximum negative
        {
            result = INT16_MIN;
            break;
        }

        result += (input[i] - '0') * multiplier; // convert to int, get its position and then add it to result.
        multiplier *= 10; // get next position
    }

    return result;
}

int main()
{
    std::string MyEx = "123456";
    int MyInt = stringToInt(MyEx);

    std::cout << MyInt;

    return 0;
}
Khalil Khalaf
  • 9,259
  • 11
  • 62
  • 104
  • 1
    from OP code and checking, you can not ensure that all the string items are digits – Humam Helfawi Sep 27 '16 at 12:37
  • @HumamHelfawi OP did not state that. Based on his example input, it is not clear that one of the chars might not be an integer. I added it anyway and thanks for pointing it out. – Khalil Khalaf Sep 27 '16 at 12:49
-3
void enforce( bool b ) {
    if ( !b ) {
        throw std::range_error("Not a valid string to convert to integer");
    }
}

int stringToInt(std::string) {
    for ( std::size_t i( 0 ); i != ( last - first ); ++i ) {
        enforce( ( '0' <= first[ i ] ) && ( first[ i ] <= '9' ) );
        result += pow(10,i) * ( first[ i ] - '0' );
    }
}

Source

MenaceInc
  • 1
  • 2