Solution for Assignment 3

#include <stdio.h>
#define CHANGE    1
#define RECTANGLE 2
#define QUIT      3

void print_menu();
void get_int(int *val);
void get_int_low(int *val, int low);
void get_int_bound(int *val, int low, int high);
void make_change(void);
void report_coins(int quarter, int dime, int nickel, int penny);
void do_rectangle(void);
void print_rectangle_menu(void);
float calc_rect_area(float length, float width);
float calc_rect_perimeter(float length, float width);

int main(void)
{
  int choice;

  do
  {
    print_menu();
    printf("\nEnter choice ");
    get_int_bound(&choice, CHANGE, QUIT);
    switch(choice)
    {
      case CHANGE: make_change();
                   break;
      case RECTANGLE: do_rectangle();
                      break;
      case QUIT: printf("\nExiting program\n\n");
    }
  }
  while (choice != QUIT);
  return 0;
}


/*function headers omitted for space considerations 
  you should have them
*/

void print_menu()
{
  printf("\nMain Menu\n");
  printf("\n1. Change pennies into larger coins");
  printf("\n2. Do some rectangle manipulations");
  printf("\n3. Quit the program");
}


void get_int(int *val)
{
  scanf("%d", val);
}


void get_int_low(int *val, int low)
{
  do
  {
    get_int(val);
    if (*val < low)
       printf("\nValue must be >= %d, Try again. ", low);
  }
  while (*val < low);
}


void get_int_bound(int *val, int low, int high)
{
  do
  {
    get_int(val);
    if ((*val < low) || (*val > high))
       printf("\nValue must be between %d and %d, inclusively."
             "\nTry again. ", low, high);
  }
  while ((*val < low) || (*val > high));
}


void get_float(float *val)
{
  scanf("%f", val);
}


void get_float_low(float *val, float low)
{
  do
  {
    get_float(val);
    if (*val < low)
       printf("\nValue must be >= %f, Try again. ", low);
  }
  while (*val < low);
}


void make_change(void)
{
  int quarters, dimes, nickels, pennies;
  int main_menu;

  do
  {
    printf("\nEnter the number of pennies ");
    get_int_low(&pennies, 0);

     /**NOTE: there are several ways of doing this part.  
        1. You could leave as it was originally. See below
        2. You could call a subprogram num_coins(&quarters, &dimes, &nickels,
           &pennies) to do the work.
        3. You could use subprograms quarters = calc_coin(pennies, 25);
                                     pennies = calc_remainder(pennies, 25);
                                     dimes = calc_coin(pennies, 10);
     **/

    quarters = pennies/25;
    pennies = pennies%25;
    dimes = pennies/10;
    pennies = pennies%10;
    nickels = pennies/5;
    pennies = pennies%5;

    report_coins(quarters, dimes, nickels, pennies);
    printf("\nEnter 1 to continue, 0 to return to the main menu ");
    get_int_bound(&main_menu, 0, 1);
  }
  while (main_menu == 1);
}

void report_coins(int quarter, int dime, int nickel, int penny)
{
   if (quarter > 0)
      if (quarter > 1)
         printf("\n%d quarters", quarter);
      else
         printf("\n%d quarter", quarter);
   if (dime > 0)
      if (dime > 1)
         printf("\n%d dimes", dime);
      else
         printf("\n%d dime", dime);
   if (nickel > 0)
      if (nickel > 1)
         printf("\n%d nickels", nickel);
      else
         printf("\n%d nickel", nickel);
   if (penny > 0)
      if (penny > 1)
         printf("\n%d pennies", penny);
      else
         printf("\n%d penny", penny);
}


void do_rectangle()
{
  float length, width, area, perimeter;
  int choice, got_vals = 0, new_vals;

  do
  {
    print_rectangle_menu();
    get_int_bound(&choice, 1, 3);
    if (choice != 3)
    {
         /** This whole section probably belongs in a subprogram due
             to its size.
         **/
       if (got_vals == 0)
       {
         printf("\nEnter values for length and width ");
         get_float_low(&length, 0.0);
         get_float_low(&width, 0.0);
         got_vals = 1;
       }
       else
       {
          printf("\nYou may either \n1. Enter new values"
                 "\n2. Use current values \nMake your choice now ");
          get_int_bound(&new_vals, 1, 2); 
          if (new_vals == 1)
          {
             printf("\nEnter values for length and width ");
             get_float_low(&length, 0.0);
             get_float_low(&width, 0.0);
             got_vals = 1;
          }
       }
    }
    switch(choice)
    { 
      case 1: area = calc_rect_area(length, width);
              printf("\nArea = %f ", area);
              break;
      case 2: perimeter = calc_rect_perimeter(length, width);
              printf("\nPerimeter = %f ", perimeter);
              break;
      case 3: printf("\nReturning to main menu");
    }
  }
  while (choice != 3);  
}


void print_rectangle_menu()
{
  printf("\nRectangle menu\n");
  printf("\n1. Calculate area of a rectangle");
  printf("\n2. Calculate perimeter of a rectangle");
  printf("\n3. Return to the main menu\n");
}


float calc_rect_area(float length, float width)
{
  return (length * width);
}


float calc_rect_perimeter(float length, float width)
{
  return (2 * (length + width));
}