# I/O in [Almost] Any Base

After climbing the ternary I/O mountain, and crafting functions that both input and output base 3 values, the next step is obvious: Combine both functions into a single program. The step after that is less obvious: Change the code so that any base can be used to process input or generate output.

Well, almost any base.

As the functions are written, then work best to translate bases that use digits 0 through 9. I assume base 11 would use ‘A’ to represent the decimal 10, just as hexadecimal does. This modification could be made to my code, but I was in a hurry to see whether it worked.

From last week’s Lesson, I crafted the base_in() function.

From the week before’s Lesson, I created the base_out() function.

To make both work with any base (as opposed to base 3), I created the defined constant `BASE`, which can be set to a value from 2 to 9:

`#define BASE 5`

The changes in each function include building the powers table:

```/* create the powers table */
powers = 1;
for(x=1;x<12;x++)
{
powers[x] = powers[x-1]*BASE;
}```

And the test for a valid digit in the input function:

```/* bail on invalid digit */
if( *(t+x)<'0' || *(t+x)>(BASE+'0') )
return(-1);```

Otherwise, the functions are pretty-much the same as shown in earlier Lessons for my ternary I/O functions. Here is the full code, which works with base 5:

### 2020_06_27-Lesson.c

```#include <stdio.h>
#include <stdlib.h>

#define BASE 5

/* translate value to string */
char *base_out(unsigned n)
{
static char tstring;
char *t;
int powers;
int x,r;

/* check for overflow */
if( n<0 || n>65535 )
{
fprintf(stderr,"%d is out of range\n",n);
exit(1);
}

/* create the powers table */
powers = 1;
for(x=1;x<12;x++)
{
powers[x] = powers[x-1]*BASE;
}

/* build the return string */
tstring = '\0';
for(x=0;x<11;x++)

r = n % powers[x+1];
n -= r;
tstring[10-x] = r/powers[x] + '0';
}

/* remove any leading zeros */
t = tstring;
x = 0;
while( *t=='0' && x<10 )

t++;
x++;
}

return(t);
}

/* translate string to value */
unsigned base_in(char *t)
{
int powers;
int len,x,r,p;

/* create the powers table */
powers = 1;
for(x=1;x<11;x++)
{
powers[x] = powers[x-1]*BASE;
}

/* translate the string */
/* find the end of the string */
len = 0;
while(1)
{
if( *(t+len)=='\n' || *(t+len)=='\0' )
{
break;
}
len++;
/* limit to 11 digits */
if( len==11 )
break;
}
/* backup over the null character */
len--;

/* process the string backward
but process the powers table forward */
r = 0;
for( x=len,p=0 ; x>=0 ; x--,p++)
{
/* bail on invalid digit */
if( *(t+x)<'0' || *(t+x)>(BASE+'0') )
return(-1);
r += ( (*(t+x)-'0') * powers[p] );
}

return(r);
}

int main()
{
unsigned b;
char *bstring;

printf("Base %d I/O\n",BASE);
/* prompt for input */
printf("Enter a decimal value: ");
scanf("%d",&b);

bstring = base_out(b);
printf("%d in base %d is %s\n",b,BASE,bstring);
printf("%s in decimal is %d\n",bstring,base_in(bstring));

return(0);
}```

The code outputs the base in the main() function, then prompts for an input value in decimal. This value is translated into the named base for output, then the base-whatever value string is translated back into decimal, proving that the thing works.

```Base 5 I/O Enter a decimal value: 12345 12345 in base 5 is 343340 343340 in decimal is 12345```