Thursday, August 28, 2008

Base conversion utility

The following code is a small utility I wrote to do base conversions to and from different bases.
Right now the support is till 2-36 base values. As of today (28th Aug) I have no intention to extend the base values. The code has been tested on Linux platform but should be portable to other platforms without any hassle. I have not tried to cover all the corner cases for error handling, but it serves a good purpose. And the algorithm is also very basic. I wanted something to just work for me :)

Any comments/views are welcome.

Useage: ./a.out -f fromBase -t toBase NumberForConversion


/*
* You are free to edit/modify/redistribute this code.
* But do acknowledge the contribution of the previous authors!
*
*/


#include < iostream>
#include < cstring>
#include < cstdlib>
#include < errno.h>

using std::cout;
using std::endl;
using std::string;

const int MAXBASE=36; /* maximal base value allowed */
const float version=1.0; /* Version of the tool */

int from, to = 10;

/* Display help for incorrect usage or if requested */
void help() {
cout << "Usage: run -f frombase [-t tobase] digit" \
"\n\t-f -- base to convert from" \
"\n\t-h -- show help" \
"\n\t-t -- base to convert to. Defaults to 10" \
"\n\t-v -- show version";
}

inline bool rightChar(const char &c)
{
return c=='-' || c=='f' || c=='t';
}

//
// Function to parse command line
//
void parse_args(char **args, int c) {
int i = 1;
char **p = args;
while(i != (c-1)) {
switch (*p[i]) {
case '-':
++p[i];
if(rightChar(*p[i])) continue;
else help();
break;
case 'f': // Get "from" base
++i;
from = strtol(p[i], 0, 10);
++i;
if (from < 2 || from > MAXBASE) {
cout << "Error: invalid from : " << p[i] << " \n";
exit(1);
}
break;
case 't': // Get "to" base
++i;
to = strtol(p[i], 0, 10);
++i;
if (to < 2 || to > MAXBASE) {
cout << "Error: invalid to : " << p[i] << "\n";
exit(1);
}
break;
case 'v': // Version
cout << "Current version number is: " << version << " \n" ;
exit(0);
case 'h': // Help
help();
exit(0);
default:
cout << "Invalid arg " << p[i] << "\n";
help();
exit(1);
}
}
}


/*
* This function converts the base ten integer to the required base
* ToReqdBase(const int& tBase, const int& dig)
* returns: int - converted integer from base 10 to the required answer
*/
string ToReqdBase(const int& tBase,const int &dig) {
int tExpr = dig;
string result = "";
//int msbMultiplier = 1;

while(tExpr) {
int tempResult = /*msbMultiplier**/(tExpr%tBase);
char tempRes = tempResult>9 ? ('A'+tempResult-10) : ('0'+tempResult);
result = tempRes + result;
//msbMultiplier *= 10;
tExpr /= tBase;
}
return result;

}

int main(int argc, char *argv[]) {
if (! (argc==6 || argc==4) ) {
help();
return 1;
}
parse_args(argv, argc);
errno = 0;
char *errCheck = 0;
int dig = strtol(argv[argc-1], &errCheck, from);
if ((errno == ERANGE && (dig == LONG_MAX || dig == LONG_MIN)) || (errno != 0 && dig == 0)) {
perror("strtol");
exit(EXIT_FAILURE);
}
if(*errCheck != '\0') { cout << " Error in input number. Check the from-base value too! \n\n Wrong answer probably"; }
cout << " " << ToReqdBase(to,dig) << "\n";
return 0;
}

1 comment:

Anonymous said...

Good post.