Changeing Program to be written with functions

I am having trouble even understanding where to start on this. I am supposed to rewrite my little tax program using Functions. Any and all help would be appreciated. I use the util.h to help me with my error correction. I tried to upload it but it is blocked.
//Author: David E. Berry
//Date: 21 May 2009, 
//Revision: 3.0.2, This version checks for only positive numbers for the sale amount
//
 
#include <stdio.h>
#include "util.h"
 
int main(int argc, char *argv[])
 
 
{
char buff[25];
int choice = 0;
char answer;
 
char input[BUFSIZ], *p;
 
double iAmountofSale; /* Represents a double precision floating point data type*/ 
  
//Section for numbers to plug into equations
 
  float iDelMarTaxRate = 0.0725;
  float iEncinitasTaxRate = 0.075;
  float iLaJollaTaxRate = 0.0775;
  float iTax_Result_DelMar = 0;
  float iTax_Result_Encinitas = 0;
  float iTax_Result_LaJolla = 0;
  float iTotal_Result_DelMar = 0;
  float iTotal_Result_Encinitas = 0;
  float iTotal_Result_LaJolla = 0;
 
//Section to choose store for Intro Text
 
 
do {   /*Starts Main loop*/
    while (choice <= 0 || choice > 4){ /*Takes only a valid menu user input*/
      system("CLS");
      printf("\n\tKudler Fine Foods Sales Tax and Total Calculation Program\n");
      printf("\n\tversion 3.0.2  Author: David E. Berry\n");
      printf("===============================================================\n");
      printf("\Sales Tax per Store location and Sales Total for that location\n\n");
      printf("\t1. DelMar\n");
      printf("\t2. Encinitas\n");
      printf("\t3. LaJolla\n");
      printf("\t4. to quit program\n");
      printf("\nEnter a number for the store of your choice: ");
      scanf("%s", buff);
      if ( !isAnumber(buff))continue; /*Continues with the loop*/
      choice = atoi(buff);  /*Converts choice input into an integer*/
      if ( choice == 4) exit(0); /*If the user choice is 4 the program quits*/
    }
 
 
//Error handling section to ensure postive interger for input
 
    
  printf("Enter purchase amount: $");
     
 
     for(;;)
     {        /* Infinite "for" loop until the user enters a postive number */
 
		fgets(input , sizeof(input), stdin);
 
		iAmountofSale = strtod(input , &p); /*This is the amount used in the calulation of the tax and total*/
 
		if(input[0] != '\n' && iAmountofSale > 0 && (*p == '\n' || *p == '\0')) break; /*This checks for only positive numbers*/
		
		else printf("Invalid input!\n\nPlease enter a positive integer for the amount: $"); /*Displays if the user did not enter a postive number*/
 
		iAmountofSale = 0;
 
      }
					
   printf("\nYou've entered the amount: $%.2f\n", iAmountofSale); /*Displays the number user input correctly*/    
    
    
    
    switch (choice) /*Takes you to the proper Case*/
         
    { 
 
    case 1:
 
        iTax_Result_DelMar = iAmountofSale * iDelMarTaxRate;  /*Does the math for DelMar Tax*/
        printf("\nSales Tax for Del Mar is $%.2f\n", iTax_Result_DelMar);
        iTotal_Result_DelMar = iAmountofSale + iTax_Result_DelMar; /*Figures the total Sale for DelMar*/
        printf("\nTotal Sale for Del Mar is $%.2f\n\n", iTotal_Result_DelMar);
        
    break;
        
    case 2:
       
        iTax_Result_Encinitas = iAmountofSale * iEncinitasTaxRate; /*Does the math for Encinitas Tax*/
        printf("\nSales Tax for Encinitas is $%.2f\n\n", iTax_Result_Encinitas); //add an \n
        iTotal_Result_Encinitas = iAmountofSale + iTax_Result_Encinitas; /*Figures the total Sale for Encinitas*/
        printf("Total Sale for Encinitas is $%.2f\n\n", iTotal_Result_Encinitas);
 
    break;     
 
    case 3:
 
       iTax_Result_LaJolla = iAmountofSale * iLaJollaTaxRate; /*Does the math for LaJolla Tax*/
       printf("\nSales for Tax La Jolla is $%.2f\n\n", iTax_Result_LaJolla);
       iTotal_Result_LaJolla = iAmountofSale + iTax_Result_LaJolla; /*Figures the total Sale for LaJolla*/
       printf("Total Sale for La Jolla is $%.2f\n\n", iTotal_Result_LaJolla);
 
    }    
 
      printf("\nWould you like to try again (y,n)? "); /*Gives the user another chance to run the program from the start*/
      choice = 0;
      answer = getchar(); 
    } while('y' == answer || 'Y' == answer); 
 
  
  return 0;
}

Open in new window

Sunset_VistaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

a_bCommented:
isAnumber is not defined. - Error
0
mrjoltcolaCommented:
Start off considering the high level business processes or steps that are happening in your program. Then organize the functions accordingly.

Something like

getInput()
calculateTax()
printOutput()


Group the code according to the _what_ is going on in each step, and then inside the function for that step write the code for _how_ it happens. The _what_ should be explainable to someone that is not a programmer.

Something like describing the steps in a supermarket for weighing and pricing fruit for a customer.
1) Choose fruit
2) Weigh fruit
3) Calculate price using per/lb cost
4) Stamp price

So keep in mind, as you break the program into functions, the variables will need to be either global variables, or will need to be inputs (parameters) to the function. The easiest way is to make all of the current variables in main() global, and then once you have rearranged it and it still works as a program, you could rewrite so that all the variables are local, which is better practice.

Make sense?

Make sense?
0
mrjoltcolaCommented:
I assume isAnumber is part of util.h as the OP suggested, but the point here is not to fix the program for him, as this is obviously homework. Please make sure to read the homework rules in the help section.
0
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

mrjoltcolaCommented:
Sorry for the double talk up there, I had a "cut-and-paste" error before submitting. :)
0
evilrixSenior Software Engineer (Avast)Commented:
Sunset_Vista, I take it this is an assignment? Please clarify.

The best way to move forward with this is to go through your existing code and isolate descrete units of code that could be extracted into seperate functions and refactor the code accordingly. As a rough guide, your code can probably be split into 3 main units, the while loop that displays the menu and captures a choice, the for loop that captures users positive number and the switch that handles the choice. Once you've sectioned off the code into these 3 units you might then want to look to break it down some more, for example each case in your switch might be a candidate for conversion to a function,
0
Sunset_VistaAuthor Commented:
Thank you for your help on this so far. I will need some time to try your suggestions as I am very new to programming. I have an even larger amount of respect for those that fully understand programming. You seem to see it as another language (no pun intended) After another seven days, I will most likely never venture into this world of programming again, it is VERY hard for me to understand.
Regretfully, I will not be able to give feedback on this until tomorrow. I need to get some rest before tomorrow starts again. I did think try to post the util.h utility by renaming it .txt. Hope it works.

util--rename-to-util.h.txt
0
evilrixSenior Software Engineer (Avast)Commented:
>> I will not be able to give feedback on this until tomorrow
No worries, take your time... it's more important to us that you understand the answers given not that we race to get the question closed :)
0
ozoCommented:
using Functions can make it easier for many people to work on a project because you can put different functions in different files and assign different people to work on each file.

It can also reduce repetition when you have similar code  in different places which you can replace with calls to one function.  Which also means that you only need to make updates in one place instead of changing each separate instance of similar code, which may be prone to accidentally  making the instances inconsistent with each other.

Can functions help you in either of these ways with this code?
Are there ways you might want to assign different aspects of the program to different people?
Are there places where repetitive code could be consolidated into one function?
Some parts of the code seem similar except for having DelMar or Encinitas or LaJolla
0
Sunset_VistaAuthor Commented:
Ozo, Thank you for the explanation about functions. Evilrix, yes this is an assignment, but the class text is NO help, that is why I came here. In the past I was came here to learn how error handling worked and was able to make that work, but by following examples, but not totally from scratch. Your suggestions of where to break down of my program into sections helps some.  MrJoltCola, your explanation is the clearest yet I still  can't seem to get started.
0
ozoCommented:
If the exercise is to become familiar with using functions, you might just try putting any part of it into a function, regardless of whether it us useful to split that part off.
(It may be easiest to start by split off something that can be done without having  to pass any parameters from the main function,
even if that may not make the most useful function, just so you will have had the experience of creating any function, which you can then embellish as you become more familiar with how to do it)
0
Infinity08Commented:
>> I still  can't seem to get started.

What's causing you problems ? Something you don't understand ? Maybe reading up on functions a bit more will make things clearer :

        http://cplusplus.com/doc/tutorial/functions/
        http://cplusplus.com/doc/tutorial/functions2/

That should give you a better idea of what functions are, what they can do, and what they can be used for.
0
Sunset_VistaAuthor Commented:
Infinity, I am using C not C++, enough the same but different enough to really get me lost. Ozo, is it possible to turn the simple 'Hello World' program into a function?
0
mrjoltcolaCommented:
You can take a program of pure statements.

main() {
   a = b + c;
   d = a + b;
   e = a * d;
}

And functionally decompose it:

main() {
   a = do_add(b, c);
   d = do_add(a, b);
   e = do_multiply(a, d);
}

int do_add(int num1, int num2) {
   return num1 + num2;
}

int do_mul(int num1, int num2) {
   return num1 * num2;
}


Yes, this is contrived and trivial, but I hope you understand, this is all functional decomposition is. You make the "whats" into functions, and hide the "hows" inside each of them. So at the top level of your main, you might be able to read some pseudo-prose high level of tasks.
0
mrjoltcolaCommented:
Typo, that should be:

int do_multiply(int num1, int num2) {
   return num1 * num2;
}
0
Sunset_VistaAuthor Commented:
MrJoltCola, Thank you VERY much for something actual to work with, this will help me greatly. I think I have enough to get started on, the light bulb is getting a little brighter.

I am going to try to turn the calculations of tax and totals into a function such as DelMar_Function for each store then call that function based on user input. Is this the right track?
0
Sunset_VistaAuthor Commented:
Here is what I have so far, had to post the whole thing in the snippet section. I think I went too far and got lost. Once I changed one thing I realized I had to change the others at the same time. It does not compile and error out with a syntax error before "void" . Not sure what that is.
//Author: David E. Berry
//Date: 26 May 2009, 2135
//Revision: 4.0.0, First try at Functions
//
 
#include <stdio.h>
#include "util.h"
 
//defined macros
#define true 1;
#define false 0;
 
//function declarations
int displayMenu();
void calc_and_display_Result(float,int);
void printTitle();
int read_user_Input();
 
//Global variables accessible from all functions
 
int choice;
double iAmountofSale; /* Represents a double precision floating point data type*/ 
 
float iDelMarTaxRate = 0.0725;
float iEncinitasTaxRate = 0.075;
float iLaJollaTaxRate = 0.0775;
float iTax_Result_DelMar = 0;
float iTax_Result_Encinitas = 0;
float iTax_Result_LaJolla = 0;
float iTotal_Result_DelMar = 0;
float iTotal_Result_Encinitas = 0;
float iTotal_Result_LaJolla = 0;
 
 
 
int main(int argc, char *argv[])
 
 
{
  char buff[25];
  int choice = 0;
  char answer;
 
  char input[BUFSIZ], *p;
 
 
  do {
      /*Starts Main loop*/
     
 
      while (choice <= 0 || choice > 4){ /*Takes only a valid menu user input*/
      system("CLS");
      printTitle();
      if(!displayMenu())
      {
       getchar();
       continue;
      }
      if (read_user_Input())
      {
         calc_and_display_Result(iAmountofSale, choice);  
      }else {
 
      }
      printf("\nWould you like to try again (y,n)? "); /*Gives the user another chance to run the program from the start*/
      choice = 0;
      answer = getchar(); 
      } while('y' == answer || 'Y' == answer); 
  
      return 0;
 
 
 
 
 
}
 
 
void printTitle() //Function that displays the title of the program
{
      printf("\n\tKudler Fine Foods Sales Tax and Total Calculation Program\n");
      printf("\n\tversion 4.0.0  Author: David E. Berry\n");
      printf("===============================================================\n");
      printf("\Sales Tax per Store location and Sales Total for that location\n\n");
}
 
 
 
 
 
 
 
int displayMenu()
{
      char buff[10];
      resetbuf(buff, 10);
 
      printf("\t1. DelMar\n");
      printf("\t2. Encinitas\n");
      printf("\t3. LaJolla\n");
      printf("\t4. to quit program\n");
      printf("\nEnter a number for the store of your choice: ");
      scanf("%s", buff);
      if ( !isAnumber(buff))continue; /*Continues with the loop*/
      choice = atoi(buff);  /*Converts choice input into an integer*/
      if ( choice == 4) exit(0); /*If the user choice is 4 the program quits*/
      return true;
}
 
 
 
int read_user_Input() //Function that reads the users input for amount of the sale
 
{
    
  printf("Enter purchase amount: $");
     
 
     for(;;)
     {        /* Infinite "for" loop until the user enters a postive number */
		fgets(input , sizeof(input), stdin);
		iAmountofSale = strtod(input , &p); /*This is the amount used in the calulation of the tax and total*/
		
                if(input[0] != '\n' && iAmountofSale > 0 && (*p == '\n' || *p == '\0')) break; /*This checks for only positive numbers*/
		
                else printf("Invalid input!\n\nPlease enter a positive integer for the amount: $"); /*Displays if the user did not enter a postive number*/
		iAmountofSale = 0;
      }
					
      printf("\nYou've entered the amount: $%.2f\n", iAmountofSale); /*Displays the number user input correctly*/    
    
    
}
 
 
 
 
 
 
void calc_and_display_Result(float iAmountofSale,int choice)
 
{  
  
    switch (choice) /*Takes you to the proper Case*/
         
    { 
 
    case 1:
 
        iTax_Result_DelMar = iAmountofSale * iDelMarTaxRate;  /*Does the math for DelMar Tax*/
        printf("\nSales Tax for Del Mar is $%.2f\n", iTax_Result_DelMar);
        iTotal_Result_DelMar = iAmountofSale + iTax_Result_DelMar; /*Figures the total Sale for DelMar*/
        printf("\nTotal Sale for Del Mar is $%.2f\n\n", iTotal_Result_DelMar);
        
    break;
        
    case 2:
       
        iTax_Result_Encinitas = iAmountofSale * iEncinitasTaxRate; /*Does the math for Encinitas Tax*/
        printf("\nSales Tax for Encinitas is $%.2f\n\n", iTax_Result_Encinitas); //add an \n
        iTotal_Result_Encinitas = iAmountofSale + iTax_Result_Encinitas; /*Figures the total Sale for Encinitas*/
        printf("Total Sale for Encinitas is $%.2f\n\n", iTotal_Result_Encinitas);
 
    break;     
 
    case 3:
 
       iTax_Result_LaJolla = iAmountofSale * iLaJollaTaxRate; /*Does the math for LaJolla Tax*/
       printf("\nSales for Tax La Jolla is $%.2f\n\n", iTax_Result_LaJolla);
       iTotal_Result_LaJolla = iAmountofSale + iTax_Result_LaJolla; /*Figures the total Sale for LaJolla*/
       printf("Total Sale for La Jolla is $%.2f\n\n", iTotal_Result_LaJolla);
 
     break;
     }    
}

Open in new window

0
mrjoltcolaCommented:
This is looking good. I expect you have a mis-matched bracket, maybe one too few } brackets? Make sure they all match up, for every { you need a }
0
mrjoltcolaCommented:
Use a little more indentation to make it easier to spot missing brackets.

See my reformatting in the snippet window below, and how easier it is to read.

Also, I note you have what appears to be an error of mixing do/while with while syntax.

while() {

} while();

The only time you use that sort of syntax is with:

do {

}
while();

The scary part about this, is it is legal in C to say

   while(something);

because ; is an empty, legal statement.

That is an infinite loop and is 99.9% never what the author intended. So by my reading of your code, you have combined the loops that check while(choice) and while(answer)


while (choice <= 0 || choice > 4){ /*Takes only a valid menu user input*/
   system("CLS");
   printTitle();
   if(!displayMenu()) {
       getchar();
       continue;
   }
   if (read_user_Input()) {
       calc_and_display_Result(iAmountofSale, choice);  
   } else {
 
   }
   printf("\nWould you like to try again (y,n)? "); /*Gives the user another chance to run the program from the start*/
   choice = 0;
   answer = getchar(); 
} while('y' == answer || 'Y' == answer); 

Open in new window

0
Sunset_VistaAuthor Commented:
mrjoltcola, Thank you for the feed back. I knew I was lost somewhere. I will try to fix the brackets and the while to no where statement tomorrow evening after duty.  
0
Sunset_VistaAuthor Commented:
MrJoltCola and all, I fixed my bracket issue, and it compiles now, but does not work as desired. User can enter choice for city, then enter amount for sale but it will not display the tax and total for that city. I have also broken my 'try again y/n' function. Would you please help me find where I went wrong.
//Kudler Fine Food Sales Tax Calculation Program for UOP Online POS/370
//Author: David E. Berry
//Date: 27 May 2009, 
//Revision: 4.0.1, SEcond try at Functions
//
 
#include <stdio.h>
#include "util.h"
 
//defined macros
#define true 1;
#define false 0;
 
//function declarations
int displayMenu();
void calc_and_display_Result(float,int);
void printTitle();
int read_user_Input();
 
//Global variables accessible from all functions
 
int choice;
double iAmountofSale; /* Represents a double precision floating point data type*/ 
 
float iDelMarTaxRate = 0.0725;
float iEncinitasTaxRate = 0.075;
float iLaJollaTaxRate = 0.0775;
float iTax_Result_DelMar = 0;
float iTax_Result_Encinitas = 0;
float iTax_Result_LaJolla = 0;
float iTotal_Result_DelMar = 0;
float iTotal_Result_Encinitas = 0;
float iTotal_Result_LaJolla = 0;
 
int main(int argc, char *argv[])
 
{
  char buff[25];
  int choice = 0;
  char answer;
  char input[BUFSIZ], *p;
 
  do {
      /*Starts Main loop*/
         system("CLS");
         printTitle();
         if(!displayMenu())
      {
              getchar();
              continue;
      }
      if (read_user_Input())
      {
          calc_and_display_Result(iAmountofSale, choice);  
      } else {
 
      }
 
      printf("\nWould you like to try again (y,n)? "); /*Gives the user another chance to run the program from the start*/
      choice = 0;
      answer = getchar();
 
      } while('y' == answer || 'Y' == answer); 
  
      return 0;
      }
      
  void printTitle() //Function that displays the title of the program
    {
      printf("\n\tKudler Fine Foods Sales Tax and Total Calculation Program\n");
      printf("\n\tversion 4.0.1  Author: David E. Berry\n");
      printf("===============================================================\n");
      printf("\Sales Tax per Store location and Sales Total for that location\n\n");
     }
 
  int displayMenu()
   {
      char buff[10];
      resetbuf(buff, 10);
      while (choice <= 0 || choice > 4){ /*Takes only a valid menu user input*/
      printf("\t1. DelMar\n");
      printf("\t2. Encinitas\n");
      printf("\t3. LaJolla\n");
      printf("\t4. to quit program\n");
      printf("\nEnter a number for the store of your choice: ");
      scanf("%s", buff);
      if ( !isAnumber(buff))continue; /*Continues with the loop*/
      choice = atoi(buff);  /*Converts choice input into an integer*/
      if ( choice == 4) exit(0); /*If the user choice is 4 the program quits*/
      return true;}
   }
    
 
 
  int read_user_Input() //Function that reads the users input for amount of the sale
 
  {
  char input[BUFSIZ], *p;  
  printf("Enter purchase amount: $");
     
 
     for(;;)
     {        /* Infinite "for" loop until the user enters a postive number */
		fgets(input , sizeof(input), stdin);
		iAmountofSale = strtod(input , &p); /*This is the amount used in the calulation of the tax and total*/
		
                if(input[0] != '\n' && iAmountofSale > 0 && (*p == '\n' || *p == '\0')) break; /*This checks for only positive numbers*/
		
                else printf("Invalid input!\n\nPlease enter a positive integer for the amount: $"); /*Displays if the user did not enter a postive number*/
		iAmountofSale = 0;
      }
      printf("\nYou've entered the amount: $%.2f\n", iAmountofSale); /*Displays the number user input correctly*/    
      }
 
 
  void calc_and_display_Result(float iAmountofSale,int choice)
 
  {  
    switch (choice) /*Takes you to the proper Case*/
  { 
    case 1:
        iTax_Result_DelMar = iAmountofSale * iDelMarTaxRate;  /*Does the math for DelMar Tax*/
        printf("\nSales Tax for Del Mar is $%.2f\n", iTax_Result_DelMar);
        iTotal_Result_DelMar = iAmountofSale + iTax_Result_DelMar; /*Figures the total Sale for DelMar*/
        printf("\nTotal Sale for Del Mar is $%.2f\n\n", iTotal_Result_DelMar);
        
    break;
        
    case 2:
        iTax_Result_Encinitas = iAmountofSale * iEncinitasTaxRate; /*Does the math for Encinitas Tax*/
        printf("\nSales Tax for Encinitas is $%.2f\n\n", iTax_Result_Encinitas); //add an \n
        iTotal_Result_Encinitas = iAmountofSale + iTax_Result_Encinitas; /*Figures the total Sale for Encinitas*/
        printf("Total Sale for Encinitas is $%.2f\n\n", iTotal_Result_Encinitas);
 
    break;     
 
    case 3:
       iTax_Result_LaJolla = iAmountofSale * iLaJollaTaxRate; /*Does the math for LaJolla Tax*/
       printf("\nSales for Tax La Jolla is $%.2f\n\n", iTax_Result_LaJolla);
       iTotal_Result_LaJolla = iAmountofSale + iTax_Result_LaJolla; /*Figures the total Sale for LaJolla*/
       printf("Total Sale for La Jolla is $%.2f\n\n", iTotal_Result_LaJolla);
 
     break;
     }    
   }

Open in new window

0
Sunset_VistaAuthor Commented:
Did I say something wrong and offend someone? It has been almost 24 hours with no response.
0
evilrixSenior Software Engineer (Avast)Commented:
I'm sure, like me, mrjoltcola is busy... I'll check back later and if he's not replied I'll take a look.
0
Sunset_VistaAuthor Commented:
Thank you, I know everyone has other primary responsibility's . I had just never seen such a gap in time. I will check back later, thanks again for the note.
0
evilrixSenior Software Engineer (Avast)Commented:
Like me I think mrjoltcola is in the UK (I think) so your last post was 5pm last night so it's possible he was not available last night and work has kept him busy today.
0
mrjoltcolaCommented:
Hi Sunset_Vista, hey didn't I watch a movie with a hotel named the same? Adam Sandler? Bedtime Stories or something...

Anyway, I am sorry I did not respond, sorry I am busy trying to do a little real work, plus have had a lot of other EE questions, mostly in the Oracle zone, so I lost track. Can you give more info, such as the program output and "how" it is not working?
0
Sunset_VistaAuthor Commented:
MrJoltCola, Sunset Vista is the name of a street back in the states West Coast Pacific Northwest to be specific, with a great view and a lot of meaning to me. I will have to add that to my list of movies to watch when I get back to where there are movies. I understand, real work is more important than this, that stuff pays the bills. I am in GMT +4 time zone, so it is late for me also, that is why I am only on for a few hours. Then have to try again another day.
The program is supposed to enable a user to select a city, enter an amount (positive integer only) and then it will output the amount entered the tax and the total sale for that city and in the end allow the user to try again, taking them back to the start.
 Now the User can enter choice for city, then enter amount for sale but it will not display the tax and total for that city. I have also broken my 'try again y/n' function. Would you please help me find where I went wrong.
0
mrjoltcolaCommented:
Can you post the most recent util.h to go along with the .c file so I can compile here?
0
Sunset_VistaAuthor Commented:
Sure thing, Here is the util.h renamed to a .txt file and the .c file
util--rename-to-util.h.txt
David-Berry-WK5-KFF-Tax-v4.0.1.txt
0
evilrixSenior Software Engineer (Avast)Commented:
>> plus have had a lot of other EE questions, mostly in the Oracle zone
Traitor :)
0
mrjoltcolaCommented:
muheheh, well its hard to get word in around here with you and i8 and jkr and ozo... ;)
0
evilrixSenior Software Engineer (Avast)Commented:
>>well its hard to get word in around here with you and i8 and jkr and ozo
You do alright... been looking at some of the Qs you've been working on today, darn good job sir :)
0
mrjoltcolaCommented:
Ok, Sunset, the problem you are running into is a common one for beginners and intermediate alike. It is something called input buffering.

When you prompt for "Try again(y/n)?"

The user enters: y <return>
The <return> is the return key, but it enterse a newline character as well. Since you are calling getchar() it reads the y or n and then proceeds. The next function that calls getchar() receives a newline (\n)

answer = getchar();  /* Consumes the y or n character only, leaves the <return> in the buffer */

So the thing probably easiest for you to do is to add an empty getchar() after the first one, to clear out the buffer. But then if theuser enters yo<return> then you have 2 characters to clear. See, it becomes a problem. If you want to handle all input then proceed to 2nd option.

Either add a loop to clear out the buffer or do what I would do and use gets() instead. gets() will read into a character array, but you can just look at the first character and ignore the rest. So instead of:

char answer;

Make it:

char answer[100];

Then instead of:

} while('y' == answer || 'Y' == answer);

Make it:

} while('y' == answer[0] || 'Y' == answer[0]);


I made those changes and the program now works for me.
0
Sunset_VistaAuthor Commented:
MrJoltCola, Thank you for the debugging. I am working on the fixes now and will report back results.
0
mrjoltcolaCommented:
Oops, I missed the important part. After the above changes:

char answer[100];

} while('y' == answer[0] || 'Y' == answer[0]);


Change:

answer = getchar();

TO:

if(gets(answer) == NULL)
  break;

0
mrjoltcolaCommented:
getchar() returns a single character.
gets() reads into a string (character array) and returns NULL if end-of-file

So gets(answer) might read:  "yaaabbbba\n"
But when you check:  while(answer[0] == 'y' ...   then you are only looking at the 1st character of the string. I hope that is clear enough.
0
Sunset_VistaAuthor Commented:
MrJoltCola, I read your very good explanation, and actually understand a little more than half of it. I then went on to make the changes suggested starting from the top. I changed the char answer and the }while statement. It now errors out when compiling  on the answer = getchar (); line saying 'incompatible types in assignment'

I went back and reread what you posted thinking I missed something and tried to insert an empty getchar (); before both of the ones that are in the snippet. Nether one helped so I took them back out.

I have attached a snippet of the code that I made changes in. I really appreciate the time you are spending to help me.
{
  char buff[25];
  int choice = 0;
  char answer[100];
  char input[BUFSIZ], *p;
 
  do {
      /*Starts Main loop*/
         system("CLS");
         printTitle();
         if(!displayMenu())
      {
             getchar();
             continue;
      }
      if (read_user_Input())
      {
          calc_and_display_Result(iAmountofSale, choice);  
      } else {
 
      }
 
      printf("\nWould you like to try again (y,n)? "); /*Gives the user another chance to run the program from the start*/
      choice = 0;
      answer = getchar();
      } while('y' == answer[0] || 'Y' == answer[0]); 
      
      return 0;
      }

Open in new window

0
mrjoltcolaCommented:
Yeh, I posted a followup right after that, you may have not seen it yet.
//Change:
 
answer = getchar();
 
//To:
 
if(gets(answer) == NULL)
  break;

Open in new window

0
Sunset_VistaAuthor Commented:
The explanation(s) is/are great!  I had troubles early on with scanf taking what ever the user put in, so changed that part to fgets for my error handling.

The program now compiles and allows the user another chance, but does not perform its intend purpose. Which is:

The program is supposed to enable a user to select a city, enter an amount (positive integer only) and then it will output the amount entered the tax and the total sale for that city and in the end allow the user to try again, taking them back to the start.

I have attached the version 3.0.2 so you could see how it is intended to work before I broke it trying to rewrite it using functions.
David-Berry-WK4-KFF-Tax-v3.0.2.txt
0
Sunset_VistaAuthor Commented:
MrJoltCola, I am fading here, no jolt cola here, only burned coffee, and its just about mid night. I am in a freak part of the world that is a half an hour ahead of the rest of the world.

I will have to hack at this some more tomorrow. I can't figure out how it is skipping my calc_and_display_Result(iAmountofSale, choice) function.
0
Sunset_VistaAuthor Commented:
MrJoltCola, I am back, and still stuck. I think it has to do with where I put my choice = 0;  or something to do with a buffer. Regardless, I can't seem to figure it out. Please give it a look when you get a chance, thank you.
0
Sunset_VistaAuthor Commented:
I will be back online in about 10 hours
0
Sunset_VistaAuthor Commented:
Hello, I know MrJoltCola was helping me, but he seems to be other wise detained. A little help from someone would be great, thank you.
0
evilrixSenior Software Engineer (Avast)Commented:
>> MrJoltCola, I am back, and still stuck. I think it has to do with where I put my choice = 0;  or something to do with a buffer. Regardless, I can't seem to figure it out. Please give it a look when you get a chance, thank you.
Please expand on this and I'll try to pick up where mrjoltcola left off.
0
Sunset_VistaAuthor Commented:
Thank you evilrix,

The program now compiles and allows the user another chance, but does not perform its intend purpose. Which is:

The program is supposed to enable a user to select a city, enter an amount (positive integer only) and then it will output the amount entered the tax and the total sale for that city and in the end allow the user to try again, taking them back to the start.

I have attached the version 3.0.2 so you could see how it is intended to work before I broke it trying to rewrite it using functions. (back in 05/28/09 11:52 AM, ID: 24496609)
0
Sunset_VistaAuthor Commented:
Here is the .c of where it is now renamed to a txt file so I can post it.
David-Berry-WK5-KFF-Tax-v4.0.2.txt
0
evilrixSenior Software Engineer (Avast)Commented:
So is 4.0.2 (I like the fact you version it) the current version?

If so we can work with that. If not can you provide current version?
0
Sunset_VistaAuthor Commented:
Evilrix, Yes, 4.0.2 is the current version. I do learn (to version things to keep track of where I am), just not quickly. The util.h file you need to compile has been posted twice up in the thread, but I will post it again if you need me to.
0
evilrixSenior Software Engineer (Avast)Commented:
Ok, I'm on it... give me a while just to (a) get it to build [I am Linux only] and (b) familiarise myself with the code.

In the words of Arnie, I'll be back :)
0
evilrixSenior Software Engineer (Avast)Commented:
Code changes made to fix it up a little, all changes commented and all comments are prefixed with RX
Have a look, let me know if you need anything exaplaining.

Also, all I've done is make it work... I've not chnages anything that I didn't need to... I'd strongly recommend you look to remove the globals and check some of your structure (for example you had if's with empty elses and a switch with no default case... meaning you couldn't see if there was a choice error). This code is far from complete in terms of being good quality but if it now works at least you have a starting point to move on from.

Best of luck.

-Rx.

NB. I put util.h as inline code... for now I'd leave it like that incase you need to report the code for further analysis. Post it in the code snippet box. Onve all bugs are fixed you can seperate it back to .cc and .h files as you wish.
//Kudler Fine Food Sales Tax Calculation Program for UOP Online POS/370
//Author: David E. Berry
//Date: 28 May 2009, 
//RevisioisAnumbern: 4.0.2, SEcond try at Functions
//
 
#include <stdio.h>
#include <stdlib.h> // RX: Need for a feew things
 
////////////////////////////////////////////////////////////////////////////////
// RX: To simplify, code is inline
//#include "util.h
/*
 * Header file implementing isAnumber function
 * Akbar Mokhtarani, POS370
 * The isAnumber function reads one character at a time
 * and check to see if it is a digit, decimal point, or 
 * negative sign and returns false (0) if it sees any other
 * character
 */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#ifndef UTIL_H //this guards against multiple inclusion of this file
#define UTIL_H
//check input for numeric values
 
// RX: Why do you need declarations immediately before you define them?
int isAnumber(char * );
void resetbuf(char*, int);
 
 int isAnumber(char*  buf){
	 int valid, i ;
	 valid = 1;
	 i=0;
  if ( buf[0] == '-')i++; //check to see if it is negative number; we accept it
   while('\0' != buf[i]){
    if (! isdigit(buf[i])&& '.' != buf[i])
			// RX: Once you know it's invalid you can terminate the loop
			valid =0;
    i++;
  }
  buf[i]=getchar(); //read the newline
  return valid;
 }
 //reset the buffer
 void resetbuf(char* b, int no){
	 // RX: What's wrong with memset(b, 0, no) ???
    int i;
     for (i=0;i<no; i++)
        b[i]='\0';
     }   
 #endif
////////////////////////////////////////////////////////////////////////////////
//defined macros
//#define true 1;
//#define false 0;
 
//function declarations
int displayMenu();
void calc_and_display_Result(float,int);
void printTitle();
int read_user_Input();
 
//Global variables accessible from all functions
 
// RX: This is really bad practice, lose these globals or you'll lose your mind
//     trying to resolve all the issues they'll end up causing you!
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// RX: int choice;
double iAmountofSale; /* Represents a double precision floating point data type*/ 
 
float iDelMarTaxRate = 0.0725;
float iEncinitasTaxRate = 0.075;
float iLaJollaTaxRate = 0.0775;
float iTax_Result_DelMar = 0;
float iTax_Result_Encinitas = 0;
float iTax_Result_LaJolla = 0;
float iTotal_Result_DelMar = 0;
float iTotal_Result_Encinitas = 0;
float iTotal_Result_LaJolla = 0;
 
int main(int argc, char *argv[])
 
{
  char buff[25];
  int choice = 0;
  char answer[100];
  char input[BUFSIZ], *p;
 
  do {
      /*Starts Main loop*/
         system("CLS");
         printTitle();
	 // RX: vvvvvvvvvvvvvvvvvvvvvvvvvv
//	  if(!displayMenu())
	  int choice = displayMenu();
	  if(choice == 4) { break; }
//      {
//             getchar();
//             continue;
//      }
	  // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      if (read_user_Input())
      {
       calc_and_display_Result(iAmountofSale, choice);
//RX:      } else {
 
      }
 
      printf("\nWould you like to try again (y,n)? "); /*Gives the user another chance to run the program from the start*/
      choice = 0;
      if (gets(answer) == NULL)
         break;
      } while('y' == answer[0] || 'Y' == answer[0]); 
      
      return 0;
      }
      
  void printTitle() //Function that displays the title of the program
    {
      printf("\n\tKudler Fine Foods Sales Tax and Total Calculation Program\n");
      printf("\n\tversion 4.0.2  Author: David E. Berry\n");
      printf("===============================================================\n");
		 // RX: printf("\Sales Tax per Store location and Sales Total for that location\n\n");
      printf("\nSales Tax per Store location and Sales Total for that location\n\n");
     }
 
  int displayMenu()
   {
		// RX: vvvvv
		int choice = 0;
		// ^^^^^^^^^
      char buff[100];
      resetbuf(buff, 10);
      while (choice <= 0 || choice > 4){ /*Takes only a valid menu user input*/
      printf("\t1. DelMar\n");
      printf("\t2. Encinitas\n");
      printf("\t3. LaJolla\n");
      printf("\t4. to quit program\n");
      printf("\nEnter a number for the store of your choice: ");
      scanf("%s", buff);
      if ( !isAnumber(buff))continue; /*Continues with the loop*/
      choice = atoi(buff);  /*Converts choice input into an integer*/
		// RX:if ( choice == 4) exit(0); /*If the user choice is 4 the program quits*/
		// RX:return 1;
		}
		// RX: vvvvv
		return choice;
		// ^^^^^^^^^
   }
    
 
// RX: This function should be returning 1 for ok and 0 for fail, currently returns nothing
  int read_user_Input() //Function that reads the users input for amount of the sale
 
  {
  char input[BUFSIZ], *p;  
  printf("Enter purchase amount: $");
     
 
     for(;;)
     {        /* Infinite "for" loop until the user enters a postive number */
		fgets(input , sizeof(input), stdin);
		iAmountofSale = strtod(input , &p); /*This is the amount used in the calulation of the tax and total*/
		
//                if(input[0] != '\n' && iAmountofSale > 0 && (*p == '\n' || *p == '\0')) break; /*This checks for only positive numbers*/
                if(input[0] != '\n' && iAmountofSale > 0 && (*p == '\n' || *p == '\0')) return 1; /*This checks for only positive numbers*/
		  
		
                else printf("Invalid input!\n\nPlease enter a positive integer for the amount: $"); /*Displays if the user did not enter a postive number*/
		iAmountofSale = 0;
      }
      printf("\nYou've entered the amount: $%.2f\n", iAmountofSale); /*Displays the number user input correctly*/  
	  
	  // RX: --->
	  return 0;
      }
 
 
// RX: calc_and_display_Result(float iAmountofSale, int choice)
void calc_and_display_Result(float iAmountofSale, int choice)
 
  {  
    switch (choice) /*Takes you to the proper Case*/
    { 
    case 1:
        iTax_Result_DelMar = iAmountofSale * iDelMarTaxRate;  /*Does the math for DelMar Tax*/
        printf("\nSales Tax for Del Mar is $%.2f\n", iTax_Result_DelMar);
        iTotal_Result_DelMar = iAmountofSale + iTax_Result_DelMar; /*Figures the total Sale for DelMar*/
        printf("\nTotal Sale for Del Mar is $%.2f\n\n", iTotal_Result_DelMar);
        
    break;
        
    case 2:
        iTax_Result_Encinitas = iAmountofSale * iEncinitasTaxRate; /*Does the math for Encinitas Tax*/
        printf("\nSales Tax for Encinitas is $%.2f\n\n", iTax_Result_Encinitas); //add an \n
        iTotal_Result_Encinitas = iAmountofSale + iTax_Result_Encinitas; /*Figures the total Sale for Encinitas*/
        printf("Total Sale for Encinitas is $%.2f\n\n", iTotal_Result_Encinitas);
 
    break;     
 
    case 3:
       iTax_Result_LaJolla = iAmountofSale * iLaJollaTaxRate; /*Does the math for LaJolla Tax*/
       printf("\nSales for Tax La Jolla is $%.2f\n\n", iTax_Result_LaJolla);
       iTotal_Result_LaJolla = iAmountofSale + iTax_Result_LaJolla; /*Figures the total Sale for LaJolla*/
       printf("Total Sale for La Jolla is $%.2f\n\n", iTotal_Result_LaJolla);
 
     break;
		 default:
		 // RX: Have a default case so we can see if choice is invalid
		  printf("Invalid choice (%d)\n", choice);
			 break;
     }    
   }

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Sunset_VistaAuthor Commented:
Evilrix, Thank you very much for the help. And very very much for the comments in the code, they will go a long way to helping me understand where I went off the path. I will go back an analyze 4.0.2 and 4.0.3 to look for the changes.

Evilrix and MrJoltCola, you have been a great help to someone in a very remote area, thank you again.
0
Sunset_VistaAuthor Commented:
Great help from two forum members working together.
0
evilrixSenior Software Engineer (Avast)Commented:
You are very very welcome. It is a pleasure helping someone who is keen to learn. We're always here if you need us :)
0
mrjoltcolaCommented:
Thanks Sunset, sorry I did not return your messages. The EE email system is not always perfect. I just checked and I did not get your messages yesterday to my inbox, so my apologies if it looked like I abandonded you. Next time you can send me a direct email to call attention if I have not responded. Good luck, pleasure helping you.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.