DrevanTonder
DrevanTonder

Reputation: 727

C++ make a string to int function

I usually program in python which has a string to integer converter built in but when i use C++ it doesn't seem to work so I decided to make my own. this is what i made so far C++:

int strtoint(string str)
{
    int values [str.length()];
    int return_value = 0;

    for (int i=0; i < str.length(); ++i)
        if(str.at(str.length()-1-i) == '1')
            values[i] = 1;
        else if(str.at(str.length()-1-i) == '2')
            values[i] = 2;
        else if(str.at(str.length()-1-i) == '3')
            values[i] = 3;
        else if(str.at(str.length()-1-i) == '4')
            values[i] = 4;
        else if(str.at(str.length()-1-i) == '5')
            values[i] = 5;
        else if(str.at(str.length()-1-i) == '6')
            values[i] = 6;
        else if(str.at(str.length()-1-i) == '7')
            values[i] = 7;
        else if(str.at(str.length()-1-i) == '8')
            values[i] = 8;
        else if(str.at(str.length()-1-i) == '9')
            values[i] = 9;
    for (int i=0; i < str.length(); ++i)
        return_value += values[i]^(10*i);
    return return_value;
}

I seem to get very weird answers like "12" returns 13 and "23" returns 11.
I know about stoi but I prefer to make my own so I can learn C++.

Upvotes: 2

Views: 614

Answers (3)

CppChris
CppChris

Reputation: 1261

You could simplify this a lot with the char conversion where you just subtract the value of '0' and the use of iterators, especially reverse iterators which make it simpler to calculate the value.

#include <cmath>
#include <string>

/*! Converts a char to an integer.
 * @param c the character to convert
 * @return the integer value [0-9] or -1 if not convertible
 */
int chartoint(const char c)
{
    auto value = (c - '0');
    if (value < 0 || value > 9)
    {
        value = -1;
    }
    return value;
}

/*! Converts a string to an integer.
 * @param string the string to convert
 * @return the converted integer value or 0 if not convertible
 */
int strtoint(const std::string& string)
{
    auto integer = 0;
    const auto begin = string.rbegin();
    for (auto it = begin, end = string.rend(); it != end; ++it)
    {
        const auto current = chartoint(*it);
        if (current == -1)
        {
            integer = 0;
            break;
        }
        else
        {
            const auto factor = static_cast<int>(std::pow(10, (it - begin)));
            integer += factor * current;
        }
    }
    return integer;
}

Test run:

#include <cassert>

int _tmain(int argc, _TCHAR* argv[])
{
    assert(strtoint("1") == 1);
    assert(strtoint("1x") == 0);
    assert(strtoint("12") == 12);
    assert(strtoint("10") == 10);

    return 0;
}

Upvotes: 0

gomons
gomons

Reputation: 1976

In C++ I use std::stringstream to convert std::string to int. Simple example I found:

#include <sstream>
#include <iostream>  //used for cout
int main()
{
    std::string str = "12345";
    std::istringstream ss(str);
    int i;
    ss >> i;
    if (ss.fail())
    {
        // Error
    }
    else
    {
        std::cout << "The integer value is: " << i;
    }
    return 0;
}

Mistakes in your code you can find in @Peter answer.

Upvotes: 4

Peter
Peter

Reputation: 36597

Three problems I can see on a quick look.

The first is that

int values [str.length()];

is not valid C++. It is using a feature from the 1999 C standard, which some C++ compilers support as an extension, but it is still not valid C++.

The second is lack of handling of 0s or errors (non-digit characters) in input.

The third is the statement

return_value += values[i]^(10*i);

^ is a bitwise XOR operator in C++. Not mathematical exponentiation.

A couple of other minor tips.

You can probably simplify your code a lot by using iterators.

Also, with all standard character sets, the roman digits are sequential, starting with '0'. So a simple way to convert a digit to the numeric value you want is digit - '0', which will convert '0' to 0, '1' to 1, .... '9' to 9.

Upvotes: 6

Related Questions