Back to C Programming Index



     
A Simple Command Line Calculator

This is a useful little tool. It's a multi-function floating point calculator that can take the first part of its input from the environment, thus you can do something like:

user_prompt> calc 349 / 3.45 | calc ^ 7

which will give the result...

108403724648448.000000

I've found it helps in places where the integer-only 'eval' command doesn't meet the need.

Cut and paste the following code into a file called 'calc.c' then compile it with something like...

cc calc.c -o calc.o -a calc

There's lots of improvements and additions you can make to this which can turn it into a very useful tool.

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

usage()
{
  printf("\nHarvey's simple floating point calculator\n");
  printf("-----------------------------------------\n\n");
  printf("Enter your query on the command line in the form...\n\n");
  printf("   calc <num1> <op> <num2>         (note the spaces)\n\n");
  printf("where num1 and num2 are numbers and 'op' may be...\n");
  printf("   +   adds the two numbers\n");
  printf("   -   Subtracts num2 from num1\n");
  printf("   x   multiplies the two numbers\n");
  printf("   /   divides num1 by num2\n");
  printf("   %%   finds the remainder from dividing num1 by num2");
  printf("   ^   raises num1 to the power of num2\n\n");
  printf("calc will return the result as a floating point number.\n\n");
}

/* =============================================================== */
/* Gets one word (delimited by a space) from the standard input... */
/* =============================================================== */
char *getword()
{
  static char word[40];
  int wordlength = 0;
  int thischar;

  /* ------------------------------- */
  /* Strip off any leading spaces... */
  /* ------------------------------- */
  while((thischar = getchar()) != EOF
         && isascii(thischar)
         && isspace(thischar));
  /* ------------------- */
  /* Now get one word... */
  /* ------------------- */
  while(thischar != EOF
        && isascii(thischar)
        && !isspace(thischar))
  {
     if(wordlength < (sizeof(word) - 1))
        word[wordlength++] = thischar;
     thischar = getchar();
  }
  word[wordlength] = '0';
  return(wordlength == 0 && thischar == EOF ? NULL : word);
}

/* ================================= */
/* This is where it really starts... */
/* ================================= */
main(argc, argv)
int argc;
char *argv[];
{
 float operand1, operand2;
 float result = 0;
 char operation;
 int counter;
 char *first = (char *)malloc(40);
 char *second = (char *)malloc(40);
 long longop1, longop2;

  /* ----------------------------------------- */
  /* Have we got two operands and an operator? */
  /* ----------------------------------------- */
  if(argc < 4)
  {
     /* ------------------------------------------------------- */
     /* NO: Try reading from stdin in case num1 is in a pipe... */
     /* ------------------------------------------------------- */
     if(argc > 2)
     {
        free(first);
        if((first = getword()) != NULL)
        {
           operation = (char)*argv[1];
           sprintf(second, "%s", argv[2]);
        }
        else
        {
           usage();
           exit(1);
        }
     }
     else
     {
        usage();
        exit(1);
     }
  }
  else
  {
     /* --------------------------------------- */
     /* 3 parameters: assume 1st is a number... */
     /* --------------------------------------- */
     sprintf(first, "%s", argv[1]);
     operation = (char)*argv[2];
     sprintf(second, "%s", argv[3]);
  }

  /* ------------------------------------------- */
  /* Put the parameters into usable variables... */
  /* ------------------------------------------- */
  operand1 = atof(first);
  operand2 = atof(second);

 /* Perform the calculation */
 switch(operation)
{
 case '+':
   result = operand1 + operand2;
   break;

 case '-':
   result = operand1 - operand2;
   break;

 case 'x':
   result = operand1 * operand2;
   break;

 case '/':
   if (operand2 != 0)           /* Notice the error-checking code. */
     result = operand1 / operand2;
   else
     printf("Divide by 0 error!\n");
   break;

  case '%':
   if (operand2 != 0)
   {
     longop1 = (long)operand1;
     longop2 = (long)operand2;
     result = (float)(longop1 % longop2);
   }
   else
   {
     printf("Divide by 0 error!\n");
   }
     break;

  case '^':
     result = operand1;
     longop2 = (long)operand2;
     for (counter = 2; counter < longop2 + 1; counter++)
       result = operand1 * result;
     break;

 default:
   printf("Invalid operation!\n");
   break;
 }

 /* Print out the result */
 printf("%f\n", result);


Find out more by searching Google here...

Google