conv.c -- simple numeric base converter

David J. MacKenzie djm at eng.umd.edu
Tue Jul 3 07:02:12 AEST 1990


/* conv - convert numbers between bases

   Usage: conv [-dho] number...

   Print the value of each given NUMBER in the output base selected
   by the options.

   Options:
   -d		Output in decimal.
   -h		Output in hexadecimal.
   -o		Output in octal.

   Non-option arguments are taken to be numbers in one of the three
   bases.  Hex numbers start with 0x; octal numbers start with 0; all
   other arguments are assumed to be decimal numbers.

   David MacKenzie <djm at eng.umd.edu>
   Public domain.
   Latest revision: 07/02/90 */

#include <stdio.h>

long convert ();
void invalid_num ();
void output ();

/* The name this program was run with. */
char *program_name;

void
main (argc, argv)
     int argc;
     char **argv;
{
  extern int optind;
  int optc;
  int output_base;

  program_name = argv[0];
  output_base = 0;

  while ((optc = getopt (argc, argv, "dho")) != EOF)
    {
      switch (optc)
	{
	case 'd':
	  output_base = 10;
	  break;
	case 'h':
	  output_base = 16;
	  break;
	case 'o':
	  output_base = 8;
	  break;
	default:
	  output_base = 0;
	  goto usage;
	}
    }

 usage:
  if (optind == argc || output_base == 0)
    {
      fprintf (stderr, "\
Usage: %s [-dho] [0xhexnum] [0octnum] [decnum] ...\n", argv[0]);
      exit (1);
    }

  for (; optind < argc; ++optind)
    output (convert (argv[optind]), output_base);

  putchar ('\n');

  exit (0);
}

long 
convert (anumber)
     char *anumber;
{
  long number;

  if (anumber[0] == '0' && anumber[1] == 'x')
    {
      /* Convert from hex; sscanf returns number of conversions performed. */
      if (anumber[2] == '\0' || sscanf (anumber + 2, "%lx", &number) == 0)
	invalid_num (anumber);
    }
  else if (anumber[0] == '0')
    {
      /* Convert from octal. */
      if (anumber[1] == '\0')
	number = 0L;
      else if (sscanf (anumber + 1, "%lo", &number) == 0)
	invalid_num (anumber);
    }
  else
    {
      /* Convert from decimal. */
      if (anumber[0] == '\0' || sscanf (anumber, "%ld", &number) == 0)
	invalid_num (anumber);
    }
  return number;
}

void 
output (number, base)
     long number;
     int base;
{
  switch (base)
    {
    case 10:
      printf ("%ld ", number);
      break;
    case 8:
      printf ("0%lo ", number);
      break;
    case 16:
      printf ("0x%lx ", number);
      break;
    }
}

void 
invalid_num (anumber)
     char *anumber;
{
  fprintf (stderr, "%s: %s: invalid number\n", program_name, anumber);
  exit (1);
}
--
David J. MacKenzie <djm at eng.umd.edu> <djm at ai.mit.edu>



More information about the Alt.sources mailing list