Convert String to Integer With Error-Checking

I want to convert a string to an integer and validate that it is an actual integer. The following is what I have. An extra pair of eyes can help me locate a possible validation error I didn't check for or a way to accomplish the same tasks but in a better way. Err_Type is an enumeration of different types of errors. All ideas are appreciated. Just trying to better my understanding of c++.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
int StrToInt(string str, Err_Type* err, int base)               
{
    int Result = 0;                                             
    *err = NO_ERR;                                              
    // Makes sure string isn't empty
    Str_RemoveChar(&str, ' ');                                  
    if (str.empty())                                            
    {
        *err = EMPTY;                                           
        return 0;                                               
    }
    // Gets number of negative signs
    int Negs = 0;                                               
    for (int i = 0; i < str.length(); i++)                      
    {
        if (str[i] == '-') Negs++;                              
        else break;                                             
    }
    // Makes sure string doesn't contain solely negative signs  
    if (!(Negs - str.length()))                                 
    {
        *err = INVALID_INPUT;                                   
        return 0;                                               
    }
    // Sets the sign of the number
    str = str.substr(Negs);                                     
    if (Negs % 2)                                               
        str = "-" + str;                                        
    // Tests the conversion of the string
    size_t idx = 0;                                             
    try {
        Result = stoi(str, &idx, base);                         
    }
    catch (invalid_argument)                                    
    {
        *err = INVALID_INPUT;                                   
        return 0;                                               
    }
    catch (out_of_range)                                        
    {
        *err = OUT_OF_RANGE;                                    
        return 0;                                               
    }
    if (idx != str.length())                                    
    {
        *err = INVALID_INPUT;                                   
        return 0;                                               
    }
    return Result;                                              
}
Last edited on
I want to convert a string to an integer and check for all possible errors. The following is what I have. An extra pair of eyes can help me locate a possible error I didn't check for or a way to accomplish the same tasks but in a better way.

I am not clear what you are asking. What is the specific error are you encountering? Or are you asking for a code review?
No sorry, I meant I was wanting to check for all possible input errors. user enters a math problem (ex: "12+7*-32"). I parse this string into a vector of strings that alternate between numeric and operator. I need to check each numeric by attempting to convert them to integers. I am asking for a code review. I am basically trying to write the best function to validate and convert a string to an integer to be used for current and future projects. Learning through the advice of the general public :)
Last edited on
If we must use error codes rather than return values exceptions, I may write something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
std::string trim( std::string str ) // remove leading, trailing space
{
    while( !str.empty() && std::isspace( str.back() ) ) str.pop_back() ;

    std::size_t pos = 0 ;
    while( pos < str.size() && std::isspace( str[pos] ) ) ++pos ;
    return str.substr(pos) ;
}

std::string collapse_sign( std::string str ) // collapse leading sign
{
    const auto pos = str.find_first_not_of( "+-" ) ;

    if( pos != std::string::npos )
    {
        bool neg = false ;
        for( std::size_t i = 0 ; i < pos ; ++i ) if( str[i] == '-' ) neg = !neg ;

        return ( neg ? "-" : "" ) + str.substr(pos) ;
    }

    else return "-" ; // all + or -  (this will result in invalid input)
}

std::string clean( std::string str ) { return collapse_sign( trim(str) ) ; }

enum class s2i { OK, EMPTY, INVALID_INPUT, OUT_OF_RANGE, INVALID_BASE } ;

std::ostream& operator<< ( std::ostream& stm, s2i status )
{
    static const std::string name[] { "OK", "EMPTY", "INVALID_INPUT", "OUT_OF_RANGE", "INVALID_BASE" } ;
    return stm << name[ int(status) ] ;
}

s2i str_to_int( std::string str, int& result, int base )
{
    result = 0 ;

    if( base < 0 || base > 36 ) return s2i::INVALID_BASE ;
    else if( str.empty() ) return s2i::EMPTY ;

    else try
    {
        str = clean(str) ;
        std::size_t pos = 0 ;
        result = std::stoi( str, std::addressof(pos), base ) ;
        if( pos == str.size() ) return s2i::OK ;
        else { result = 0 ; return s2i::INVALID_INPUT ; }
    }

    catch( const std::out_of_range& ) { return s2i::OUT_OF_RANGE ; }
    catch( const std::exception& ) { return s2i::INVALID_INPUT ; }
}

http://coliru.stacked-crooked.com/a/2bb01e8de91e9b65
Last edited on
Thank you. You've made me rethink some of my logic and clean up my code some more. thank you very much.
Topic archived. No new replies allowed.