@tinstaafl ... a Dani Virtuoso indeed ... very well designed and developed ... and demos the efficent code that can be often obtained by the use of tables.
This variant, with validation of user input, may want some more testing ... but it seems to do the job of limiting input to a valid range ... well maximizing the range of numbers that can be converted ... limited only by the number of bits in an unsigned long.
It first prints out a table ... a table of max digits and max (string) value that can be obtained ... if limited by the intermediary use for storage in an unsigned long (commonly these days ... 32 bits)
// baseConversion_tinstaafl.cpp //
#include <iostream>
#include <iomanip>
#include <sstream>
#include <cctype> // re. toupper
#include <climits>
using namespace std;
typedef unsigned long UL;
const unsigned int NUM_BITS = sizeof(UL) * 8;
const UL MAX_UL = ULONG_MAX;
// to track max values of other base numbers
// that fit into a UL ...
struct Values
{
string max_value; // string max value
unsigned int num_digits; // max num base digits that fit
} ;
// GLOBAL ARRAY! Holds a TABLE of (above) Values ...
// to ease using index only in range of 1..36
Values TABLE[ 36+1 ]; // index 0 is NOT used here
const string REP = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// call this at BEGINNING of program ... to fill table
void fill( Values table[] );
string toBaseX( UL input, int nbase ) …