TIP: Click on subject to list as thread! ANSI
echo: c_plusplus
to: FRANK MASINGILL
from: CLIFF RHODES
date: 1997-08-28 16:55:00
subject: Calculator

Frank, you haven't messaged back about the last version of the 
calculator. I was hoping you'd have some questions or comments.
One area where it was still weak is in the input. The user could input 
a value that might be bad. This could lead to some problems. I have 
modified the program again to fix this. I added a function getint() 
that gets an int value from the stdin. If the value is not an int, 
getint() returns a 0. I have replaced the scanf()'s with loops 
containing getint(). Take a look at it and see what you think. This 
kind of thing is important to keep programs from blowing up on the 
user.
After this I think it is in pretty good shape--for a C program. It is 
now time to do a conversion to C++, if you want to. The first thing to 
do is go back to the design stage before you write any code. What are 
the objects involved? How do the objects interact? Those are the sort 
of questions to answer. If you want to work through this a step at a 
time, post a message with your view of the objects involved. You'll 
find you have to look at the problem in a way different from C.
#include 
#include    // For atoi() prototype
#include 
#include 
// Add this to give us some easy names for the calculations
enum Operation { Add = 0, Subtract, Multiply, Divide, NoOp };
int  getint(int *i);
int  menu(void);
int  calc(Operation op);
void promptc(int x, int y, int color , const char *p);
int main(void)
{
  while (menu())
    ;
  clrscr();
  promptc(1, 1, 11, "Thanks for playing!");
  return 0;
}
 
int getint(int *i)
{
   // Gets an value from the standard input. If the value is an int 
   // (or can be interpretted as an int) the function returns a 1 with
   // the int value at *i. Otherwise the function returns a 0;
#define INTLEN  3   // How many characters in a large int (up to 999)
   char str[INTLEN + 1];
   cputs("       \b\b\b\b\b\b\b"); // Clear the input field
   fgets(str, sizeof(str), stdin); // Safe way to input a string
   if(isdigit(str[0]))   // Make sure we have a number
   {
      *i = atoi(str);  // Convert number to int.
      return 1;        // Report good input
   }
   return 0;   // Report non-int input
}
int menu()
{
   int i, col = 30;
   clrscr();
   promptc(col, 10, 14, "Would you like to practice a little");
   col=35;
   promptc(col, 12, 14, "1. Addition?");
   promptc(col, 13, 10, "2. Subtraction?");
   promptc(col, 14, 13, "3. Multiplication?");
   promptc(col, 15, 11, "4. Division?");
   promptc(col, 16, 12, "5. or just Quit?");
   do
   {
     do
     {
        promptc(col, 20, 15, "Enter your choice: ");
     }while(!getint(&i));
     switch(i)
     {
       case 1: calc(Add);      break;
       case 2: calc(Subtract); break;
       case 3: calc(Multiply); break;
       case 4: calc(Divide);   break;
       case 5: break;
     }
   }while (i  5);
   return (i == 5) ? 0 : 1;
}
int calc(Operation op)
{
   /* Performs the calculation type specified by the Operation.
    * Still lacks adequate input protection and checking!
    */
   
   /* Several arrays of labels follow. These assume that the
    * Operation Add has a value of 0, Subtract 1, etc. 
    */
   static const char *type[] = {
         "ADDITION", "SUBTRACTION", "MULTIPLICATION", "DIVISION" };
   static const char *arg1[] = {
         "first number (Addend)",
         "number to subract FROM (Minuend)",
         "number to be multiplied (MULTIPLICAND)",
         "number to be divided (DIVIDEND)"
   };
   static const char *arg2[] = {
         "second number (Addend)",
         "number to subract (Subtrahend)",
         "number to multiply it by (MULTIPLIER)",
         "number to divide it by (DIVISOR)"
   };
   static const char *ask[] = {
         "(called the SUM)",
         "(REMAINDER)",
         "(PRODUCT)",
         "(QUOTIENT)"
   };
   // A list of colors for each Operation type
   static const int colors[] = { 14, 10, 13, 11 };
   int num1, num2, guess, ans;
   if(op >= NoOp)   // Error, this should not happen
      return 1;
   do      // In case the user wants to do another problem, loop here
   {
      int col = 20;
      clrscr();
      gotoxy(col, 10);
      textcolor(colors[op]);
      cprintf("%s PROBLEM:", type[op]);
      do
      {
         gotoxy(col, 12);
         cprintf("Type in the %s: ", arg1[op]);
      }while(!getint(&num1));
      do    // Add a loop on num2 to make sure num2 != 0 for Divide
      {
         gotoxy(col, 13);
         cprintf("Type in the %s: ", arg2[op]);
      }while(!getint(&num2) || (op == Divide && num2 == 0));
      do
      {
         gotoxy(col, 14);
         cprintf("What do you think is the answer %s? ", ask[op]);
      }while(!getint(&guess));
      switch(op)
      {
         case Add:       ans = num1 + num2; break;
         case Subtract:  ans = num1 - num2; break;
         case Multiply:  ans = num1 * num2; break;
         case Divide:    ans = num1 / num2; break;
      }
      gotoxy(col, 15);
      cprintf("The answer is ");
      textcolor(15);
      cprintf("%d", ans);
      textcolor(2);
      gotoxy(col, 16);
      cprintf("You guessed %s", (ans == guess) ? "right!" : "wrong.");
      gotoxy(col, 18);
      cprintf("Would you like to try another (Y/N)? ");
      do
      {
         guess = (0 == (guess = getch())) ? -getch() : guess;
         guess = toupper(guess);
      } while(guess != 'Y' && guess != 'N');
   } while(guess == 'Y');  // If yes, loop through calc() again
   return 0;
}
  
void promptc(int x, int y, int color, const char *p)
{
   gotoxy(x,y);
   textcolor(color);
   cputs(p);
}
Cliff Rhodes
cliff.rhodes@juge.com
crhodes@flash.net
X CMPQwk 1.42 1692 X"The wisest men follow their own direction." - Euripides
--- Maximus/2 3.01
---------------
* Origin: COMM Port OS/2 juge.com 204.89.247.1 (281) 980-9671 (1:106/2000)

SOURCE: echomail via exec-pc

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.