Skip to content

Instantly share code, notes, and snippets.

@OrangeTide
Created March 11, 2016 01:49
Show Gist options
  • Save OrangeTide/c591b0d4dcce27cedf59 to your computer and use it in GitHub Desktop.
Save OrangeTide/c591b0d4dcce27cedf59 to your computer and use it in GitHub Desktop.
command-line utility to convert numbers to different formats (hexidecimal, octal, binary, decimal, base-N)
/* base.c : command-line utility to convert numbers to different formats.
* March 10, 2016 - PUBLIC DOMAIN */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <limits.h>
int main(int argc, char **argv)
{
int i;
unsigned outbase = 10;
for (i = 1; i < argc; i++) {
const char *s = argv[i];
if (!strcmp(s, "-h")) {
fprintf(stderr,
"usage: %s [-o] [-b] [-x] [-d] <numbers....>\n"
" -b output in binary (base-2)\n"
" -o output in octal (base-8)\n"
" -d output in decimal (base-10)\n"
" -b output in hexidecimal (base-16)\n"
"numbers may be in the following formats:\n"
" [1-9][0-9]* decimal input\n"
" 0x[0-9A-F][0-9A-F]* hexidecimal input\n"
" 0b[01][01]* binary input\n"
" 0[0-7]* octal input\n"
" [0-9][0-9]'[0-9a-z] base NN format (2-36)\n",
argv[0]);
return EXIT_FAILURE;
} else if (!strcmp(s, "-o")) {
outbase = 8;
continue;
} else if (!strcmp(s, "-b")) {
outbase = 2;
continue;
} else if (!strcmp(s, "-x")) {
outbase = 16;
continue;
} else if (!strcmp(s, "-d")) {
outbase = 10;
continue;
}
char *endptr;
unsigned b;
const char *quote = strchr(s, '\'');
if (quote) {
errno = 0;
b = strtol(s, &endptr, 10);
if (errno) {
perror("strtol()");
return EXIT_FAILURE;
}
if (*endptr != '\'' || b < 2 || b > 36) {
errno = EINVAL;
perror("base must be from 2 to 36");
return EXIT_FAILURE;
}
s = quote + 1;
} else {
if (!strncmp(s, "0b", 2)) { /* binary */
s += 2;
b = 2;
} else {
b = 0;
}
}
errno = 0;
long v = strtol(s, &endptr, b);
if (errno) {
perror("strtol()");
return EXIT_FAILURE;
}
if (endptr == s) {
errno = EINVAL;
perror("empty string");
return EXIT_FAILURE;
}
if (*endptr) {
errno = EINVAL;
perror("trailing garbage");
return EXIT_FAILURE;
}
switch (outbase) {
case 2: {
unsigned long m = LONG_MIN;
while (m > (unsigned long)v)
m >>= 1;
putchar(' ');
do {
putchar("10"[!(m & v)]);
m >>= 1;
} while (m);
break;
}
case 8:
printf(" %#lo", v);
break;
case 16:
printf(" %#lx", v);
break;
default:
printf(" %ld", v);
}
}
printf("\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment