Checking if input is a string or an integer I'm teaching myself C++ by reading Stroupstrup's Programming Principles and Practice Using C++, and I'm working on an exercise in chapter 4. The exercise asks to convert input as a digit to the corresponding spelled-out value e.g. input of 1 gives the output "one".

#include "std_lib_facilities.h"

using namespace std;

//Workaround for compiler issue.
int stoi( const std::string&amp; str, std::size_t* pos = 0, int base = 10 )
    {
        const char* begin = str.c_str() ;
        char* end = nullptr ;
        long value = std::strtol( begin, &amp;end, base ) ;

        if( errno == ERANGE || value &gt; std::numeric_limits&lt;int&gt;::max() )
            throw std::out_of_range( "stoi: out ofrange" ) ;

        if( end == str.c_str() )
            throw std::invalid_argument( "stoi: invalid argument" ) ;

        if(pos) *pos = end - begin ;

        return value ;
    }


int main()
{
    struct Numbers
    {
        string spelled;
        int digit;
    };
    const Numbers nums[]
    {
        {"zero", 0},
        {"one", 1},
        {"two", 2},
        {"three", 3},
        {"four", 4},
        {"five", 5},
        {"six", 6},
        {"seven", 7},
        {"eight", 8},
        {"nine", 9},
        {"ten", 10}
    };

    string response = " ";

    cout &lt;&lt; "Type a number either spelled out or as a digit.\n";

    cin &gt;&gt; response;
    if(response.size() == 1)
    {
        cout &lt;&lt; nums[stoi(response)].spelled;
    }
    else if(response.size() &gt; 1)
    {
        for(int i=0; i&lt;=10; ++i)
        {
            if(response == nums[i].spelled)
            {
                cout &lt;&lt; nums[i].digit &lt;&lt; endl;
                break;
            }
            else;
        }
    }
}


Is there a better way to check the type of input the user gives other than checking the response size? Would it have been easier/more efficient if I had used a vector? In my for loop, does that break in the if statement break the loop?
This is now a conflict:

using namespace std;

//Workaround for compiler issue.
int stoi( const std::string&amp; str, std::size_t* pos = 0, int base = 10 )


There is an stoi in the standard namespace. Because you used using this will be considered with your function. They both have the same parameter types so this should generate a compiler error.

The only reason it may not be doing so is that you are using an archaic version of the language.

You have to reset errno to a zero state before using a function that sets it (std::strtol does not change the value if there is no error it just sets the value if there is an error).

    if( errno == ERANGE || value &gt; std::numeric_limits&lt;int&gt;::max() )
        throw std::out_of_range( "stoi: out ofrange" ) ;


This will fail if a previous library call set errno to ERANGE.

Don't like the extra indention of you r function:

int stoi( const std::string&amp; str, std::size_t* pos = 0, int base = 10 )
    {
^^^^!


Prefer to use {} around block statements.

if( errno == ERANGE || value &gt; std::numeric_limits&lt;int&gt;::max() )
            throw std::out_of_range( "stoi: out ofrange" ) ;

// Best to be safe
// So consistent use of '{}' is usually best.
if( errno == ERANGE || value &gt; std::numeric_limits&lt;int&gt;::max() ) {
            throw std::out_of_range( "stoi: out ofrange" ) ;
}


Readability enhanced by using another line:

if(pos) *pos = end - begin ;

// Easier to read for your next maintainer.
if(pos) {
    *pos = end - begin ;
}