Problem with function. Please help!

This is a discussion on Problem with function. Please help! within the C Programming forums, part of the General Programming Boards category; Hi, I have this program that doesn't do much presently except return the value of two functions to main(). The ...

  1. #1
    Registered User
    Join Date
    Jan 2006
    Posts
    100

    Problem with function. Please help!

    Hi,
    I have this program that doesn't do much presently except return the value of two functions to main(). The program is supposed to first test the value of the credit limit. First it tests to see that its in the allowed range, then it jumps to the next function that tests the account balance. It tests to make sure the account balance is not less than 0, and not more than the credit limit. The last if statement checks to see that it is in range and if so it returns the value to main. The "break" statement is just to make it leave that loop so it doesnt display 2 error messages when (validate == 2). While testing it, I discovered that when the program gets to the last if statement in the Get_Acc_Bal function, which is where it goes after "break" is executed, the Get_Credit_Limit function that is there to restart the program after there are too many errors, only gets as far as prompting for input, and then stops for no reason, ending the program. Now, this is the same function that the program starts with and has no problem completing, but when it is called within the body of the Get_Acc_Bal function, it doesn't finish and ends the program. Is there something wrong with calling a function from within the definition of another? I know that's what we all do from inside main() but is this different because they're user defined functions?

    To get to this point in the program, you can enter at the prompts in order: 600, -89, -89, 600. After the "ERROR:Too many errors, starting new customer" line is where the Get_Credit_Limit function is called and fails. Any help would be appreciated.




    Code:
     #include <stdio.h>
    
    double Get_Credit_Limit(void);
    double Get_Acc_Bal(double);
    
    
    main()
    
    {
    	double returned_credit_limit=0,
    		   returned_account_balance;	
    			
    
    	returned_credit_limit = Get_Credit_Limit();
    	returned_account_balance = Get_Acc_Bal(returned_credit_limit);
    
    }/*--------------------------end of main-----------------------------------*/
    
    
    double Get_Credit_Limit(void)
    
    {
    	
    	int validate = 0;
    	double credit_limit=0;
    	
    
    do
    
    {
    	
    	printf("\nPlease enter the credit limit: ");
    	scanf("%lf" , &credit_limit);
    	
    
    
    	if( (credit_limit >= 500.00) && (credit_limit <= 20000) )
    
    		return credit_limit;
    
    	else
    		
    		++validate;
    		
    		if(validate == 2)
    		
    		{
    			printf("\nERROR:To many errors, starting new customer.\n\n"); 
    			validate = 0;
    			credit_limit = 0;
    		
    			
    		}
    }
    
    while(validate < 3);
    
    }/*--------------------------end of Get_Credit_Limit-------------------------------------*/
    		
    
    double Get_Acc_Bal(double returned_credit_limit)
    
    {
    	
    	double account_balance;
    	int validate = 0;
    
    do
    
    {
    	
    	printf("\nPlease enter your account balance: ");
    	scanf("%lf" , &account_balance);
    
    
    	if(account_balance < 0) 
    	
    	{																		++validate;
    		
    		if(validate == 2)
    			
    			break;
    		
    		else
    				
    			printf("\nERROR:Balance cannot be negative. Try again.");
    			
    	}
    	
    
    	if(account_balance > returned_credit_limit)
    
    	{
    		printf("\nERROR:Account balance too high, starting new customer.");
    		Get_Credit_Limit();
    	}
    
    	
    	if( (account_balance > 0) && (account_balance < returned_credit_limit) )
    
    		return account_balance;
    }
    
    while(validate < 3);
    
    
    if(validate == 2)   /*--jumps to here after 'break'---------------------------*/
    
    		{
    			printf("\nERROR:Too many errors, starting new customer.\n\n");
    			returned_credit_limit = 0;
    			/*validate = 0;*/
    		    Get_Credit_Limit();
    		}
    
    }

  2. #2
    old man
    Join Date
    Dec 2005
    Posts
    90
    Well, here's a repaired version --

    The main problem is that you can't call an earlier function and think that you're "starting over" ... you're going to return from that function, and then you get unexpected recursive side-effects. (Recursion is something to do on purpose or not at all.) [edit: actually I'm not so sure that the problem is related at all to recursion ... I'm still looking it over.] To solve that I kludged a loop in main() and added "fail" values to your functions. You should always return something when it's not a void function anyway.

    I also didn't think the do...while's were very clear or efficient. Of course, you don't need to change those, I just provided an option.

    Code:
    #include <stdio.h>
    
    double Get_Credit_Limit(void);
    double Get_Acc_Bal(double);
    
    
    int
    main (void)
    {
      double returned_credit_limit = 0,
        returned_account_balance;	
    
      while (1)
      {
        if ((returned_credit_limit = Get_Credit_Limit()) == 0)
          continue;
        if ((returned_account_balance
              = Get_Acc_Bal (returned_credit_limit)) == 0)
          continue;
        break;
      }
      printf ("\nBalance: $%.2f ... Limit: $%.2f\n\n",
          returned_account_balance, returned_credit_limit);
      return 0;
    
    }/*---- end of main -----------------------------------*/
    
    
    double
    Get_Credit_Limit (void)
    {
      int validate = 0;
      double credit_limit = 0;
    	
    
      while (validate < 2)
      {
        printf("\nPlease enter the credit limit: ");
        scanf("%lf", &credit_limit);
    
        if ((credit_limit >= 500) && (credit_limit <= 20000))
          return credit_limit;
    
        printf ("\nMust be above 500 and less than 20000. "
            "Try again\n");
          ++validate;
      }
      printf("\nERROR: Too many errors, starting new customer.\n\n"); 
      return 0;
    
    }/*---- end of Get_Credit_Limit ------------------------------*/
    		
    
    double
    Get_Acc_Bal (double returned_credit_limit)
    {
      double account_balance;
      int validate = 0;
    
      while (validate < 2)
      {
        printf("\nPlease enter your account balance: ");
        scanf("%lf" , &account_balance);
    
        if (account_balance < 0)
        {
          ++validate;
          printf("\nERROR: Balance cannot be negative. Try again.\n");
          continue;
        }
    
        if (account_balance > returned_credit_limit)
        {
          printf("\nERROR: Account balance too high, "
              "starting new customer.\n\n");
          return 0;
        }
    
        if ((account_balance > 0) 
          && (account_balance < returned_credit_limit))
        return account_balance;
      }
      printf("\nERROR: Too many errors, starting new customer.\n\n");
      return 0;
    }
    Last edited by eerok; 01-30-2006 at 12:17 AM.

  3. #3
    Registered User
    Join Date
    Jan 2006
    Posts
    100
    Wow, thanks!
    I'm fairly new to this so I don't know what recursion is, but first I can see that what you did is more efficient and the "do while" stuff not neccessary. I think the continue statement immediately starts the loop over from the beginning rather than have it check the rest of the "ifs" for no reason?? After all, if that first "if" is false theres no reason to check the others right?

    I'm confused as to what you did in the body of main(), and how the functions are starting over. (What I did seemed like the natural thing to do!) But you got them to restart somehow. Can you tell me what the main() while loop is doing?(Im guessing that ((returned_credit_limit = Get_Credit_Limit()) == 0) is read as " if the assignment of Get_Credit_Limit to returned_credit_limit is equal to 0" ??)

  4. #4
    Registered User
    Join Date
    Jan 2006
    Posts
    100
    When I used Get_Credit_Limit in the third "if", in Get_Acc_Bal it works fine. It just wont work in the last "if".

  5. #5
    old man
    Join Date
    Dec 2005
    Posts
    90
    Quote Originally Posted by richdb
    I'm confused as to what you did in the body of main(), and how the functions are starting over.
    The "continue" just goes back to the while loop if the function fails (I used zero as an arbitrary fail value). When both functions succeed, "break" exits the loop.

    When I used Get_Credit_Limit in the third "if", in Get_Acc_Bal it works fine. It just wont work in the last "if".
    Well, what you really want to do is start over if you don't get a good value, so the best idea is to just do that. I'm still not sure why that was broken in your version, though. You should be able to call Get_Credit_Limit() from there ... or maybe I'm just too tired to see the problem right now.

    BTW, I didn't change that third "if" statement, but actually it's redundant since you've checked those conditions already.

    Also, you don't really need to use "else" after a break or return ... if you're still there, then there you are
    Last edited by eerok; 01-30-2006 at 02:21 AM.

  6. #6
    Registered User
    Join Date
    Jan 2006
    Posts
    100
    Where is that "1" in the while condition coming from?

  7. #7
    Registered User
    Join Date
    Dec 2005
    Location
    USA
    Posts
    29
    I presume you are asking about the following section...

    Code:
      while (1)
      {
        if ((returned_credit_limit = Get_Credit_Limit()) == 0)
          continue;
        if ((returned_account_balance
              = Get_Acc_Bal (returned_credit_limit)) == 0)
          continue;
        break;
      }
    If so, the 1 just evaluates to TRUE -- (0 is FALSE). Incidentally, I believe any positive value equates to TRUE).

    Anyway, the line...

    Code:
    while (1)
    ... is often used in a program to repeat indefinately. In this case, it would try and repeat indefinately... but the repetitions will stop, if/when execution reaches the 'break' statement at the end of the while loop.

    I hope that makes sense.

    Eddie

  8. #8
    Registered User
    Join Date
    Dec 2005
    Location
    USA
    Posts
    29
    I've tried running the program as posted by eerok.

    It seems to be working as expected (as far as I understand it).

    Just as an FYI, recursion is when a function calls itself as part of it's execution. This often helps us programmers by allowing us to break a hard problem into a series of easier problems.

    For example, if you had to compute n factorial (which is n * n-1 * n-2 .... * 1), e.g. 6 factorial is 6 * 5 * 4 * 3 * 2 * 1... you could do this using recursion by saying that the solution for n factorial is actually the same as n * (n-1 factorial). Given this, we could write a recursive function to work out the factorial of a number like so...

    Code:
    int factorial(int n)
    {
    	if ( n == 1 )
    	{
    		return n;
    	}
    	else
    	{
    		return n * factorial(n-1);
    	}
    }
    Notice that the factorial function calls itself :-) ... this is basically the definition of recursion.

    Good luck with your programming work.

    Eddie.

  9. #9
    Registered User
    Join Date
    Jan 2006
    Posts
    100
    I thought that something that goes in a while's parenthesis would have to be a variable with the "value" of 1 or 0. Didn't know you could just stick the value itself in there without using a variable in it's place.

    So if I put a 0 in there the loop should never run?

    And thanks for the recursion explanation
    Last edited by richdb; 01-30-2006 at 05:59 PM.

  10. #10
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    If so, the 1 just evaluates to TRUE -- (0 is FALSE). Incidentally, I believe any positive value equates to TRUE).
    Any number except 0 is true. 1, 34, 538985, -4, -354554, and 3333 are all true.
    So if I put a 0 in there the loop should never run?
    Precicely.

    When I write a forever loop (which differs from an infinite loop; infinite loops are unintentional), I like to use a for loop:
    Code:
    for(;;) {
    If the conditional expression is missing from a for loop, it is true.

    I thought that something that goes in a while's parenthesis would have to be a variable with the "value" of 1 or 0. Didn't know you could just stick the value itself in there without using a variable in it's place.
    It can be any valid expression. The operators (like <=) return a zero or a non-zero result, so code like
    Code:
    while(x < 10) {
    evaluated to (if x is 4)
    Code:
    while(4 < 10) {
    and since 4 is < 10, that's like
    Code:
    while(1) {
    You can even have compilcated expressions that involve functions:
    Code:
    while((!end_of_file() && read_input()) || quit) {
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 10-29-2008, 06:33 AM
  2. wxWidgets link problem
    By cboard_member in forum C++ Programming
    Replies: 2
    Last Post: 02-11-2006, 01:36 PM
  3. Problem with Visual C++ Object-Oriented Programming Book.
    By GameGenie in forum C++ Programming
    Replies: 9
    Last Post: 08-29-2005, 11:21 PM
  4. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  5. Problem with function pointers
    By vNvNation in forum C++ Programming
    Replies: 4
    Last Post: 06-13-2004, 06:49 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21