#1
  1. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Location
    Manila, Philippines
    Posts
    64
    Rep Power
    5

    Functions: ceil() and floor()


    Hi guys,

    So our problem goes like this:

    * A parking lot charges 50 units for the first 3 hours.
    * 10 units will be charged for every additional hour.
    * A fraction of an hour (e.g. 30 minutes) is still considered an hour and will be charged as such.


    Here is the program I have so far to compute the parking fee:
    Code:
    // Function of parking fee
    
    #include <stdio.h>
    #include <math.h>
    
    int main (void)
    {
    	float hrs, fee, temp;
    	
    	do
    	{
    		printf ("Enter no. of hours: ");
    		scanf (" %f", &hrs);
    		if (hrs <= 0)
    		{
    			printf ("Your input is invalid!\n\n");
    		}
    	}
    	while (hrs <= 0);
    	
    	if (hrs >= 3)
    	{
    		fee = (10 * hrs) + 20;
    		temp = ceil (fee);
    		printf ("Your parking fee is: %.2f", temp);
    	}
    	
    	else
    	{
    		fee = 50;
    		printf ("Your parking fee is: %.2f", fee);
    	}
    	
    	return 0;
    }
    I cannot get ceil() to work. When I enter 10.5 hours for example, it returns 125 when it should be 130. :confused:
    Last edited by kathyrollo; May 29th, 2013 at 02:14 AM.
  2. #2
  3. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,053
    Rep Power
    9398
    As I understand it, the hour is supposed to be rounded up and not the price. Right?
  4. #3
  5. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Location
    Manila, Philippines
    Posts
    64
    Rep Power
    5
    I coded it so the fee is the one to be rounded up.

    EDIT:
    Oh wait, wait. Let me check that again. You are right, the hour should be the one rounded up. I will post an updated code.
    Last edited by kathyrollo; May 29th, 2013 at 03:43 AM.
  6. #4
  7. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Location
    Manila, Philippines
    Posts
    64
    Rep Power
    5
    Here is the updated version:
    Code:
    // Function for parking fee
    
    #include <stdio.h>
    #include <math.h>
    #define CEIL_HRS ceil (hrs)
    
    int main (void)
    {
    	float hrs;
    	
    	do
    	{
    		printf ("Enter no. of hours: ");
    		scanf (" %f", &hrs);
    		if (CEIL_HRS <= 0)
    		{
    			printf ("Your input is invalid!\n\n");
    		}
    	}
    	while (CEIL_HRS <= 0);
    	
    	printf ("Your parking fee is: %.2f",
    		(CEIL_HRS >= 3) ? ((10 * CEIL_HRS) + 20) : (50));
    		
    	return 0;
    }
    What do you think guys?
    Last edited by kathyrollo; May 29th, 2013 at 06:21 PM.
  8. #5
  9. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,381
    Rep Power
    1871
    > #define CEIL_HRS ceil (hrs)
    I think this macro is awful.

    It's only 1 character shorter than writing it out properly, and it has no use at all if your variable is called something else.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  10. #6
  11. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,053
    Rep Power
    9398
    It also hides the fact that you're calling a function every single time you use the macro. Very inefficient.
  12. #7
  13. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Location
    Manila, Philippines
    Posts
    64
    Rep Power
    5
    Thank you for the input guys. I've seen it in StackOverflow yesterday while Googling around, so I took it in, maybe it wasn't the best method. :p
    Code:
    // Function for parking fee
    
    #include <stdio.h>
    #include <math.h>
    
    int main (void)
    {
    	float hrs;
    	
    	do
    	{
    		printf ("Enter no. of hours: ");
    		scanf (" %f", &hrs);
    		if (ceil (hrs) <= 0)
    		{
    			printf ("Your input is invalid!\n\n");
    		}
    	}
    	while (ceil (hrs) <= 0);
    	
    	printf ("Your parking fee is: %.2f",
    		(ceil (hrs) >= 3) ? ((10 * ceil (hrs)) + 20) : (50));
    		
    	return 0;
    }
    Is this more proper?
    Last edited by kathyrollo; May 29th, 2013 at 06:46 PM.
  14. #8
  15. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,381
    Rep Power
    1871
    > printf ("Enter no. of hours: ");
    You should follow this with fflush(stdout); to guarantee that the user will see the prompt before reading the input. The output stream is flushed automatically if the last char of printf is "\n".

    > scanf (" %f", &hrs);
    scanf returns a result, perhaps you should check it, and act accordingly.

    > if (ceil (hrs) <= 0)
    You do ceil(hrs) in so many places, perhaps do it once?
    Say
    hrs = ceil(hrs)
    if ( hrs <= 0 )
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2013
    Posts
    2
    Rep Power
    0
    Why are you using ceil() at all to test whether the hours are <= 0? Get rid of the ceil() in the do-while loop:

    if ( hrs <= 0f ) ...

    No one reading behind you will understand why you used ceil(), when you're not testing a value that needs to be rounded.

    Originally Posted by salem
    > printf ("Enter no. of hours: ");
    You should follow this with fflush(stdout); to guarantee that the user will see the prompt before reading the input. The output stream is flushed automatically if the last char of printf is "\n".

    > scanf (" %f", &hrs);
    scanf returns a result, perhaps you should check it, and act accordingly.

    > if (ceil (hrs) <= 0)
    You do ceil(hrs) in so many places, perhaps do it once?
    Say
    hrs = ceil(hrs)
    if ( hrs <= 0 )
  18. #10
  19. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Location
    Manila, Philippines
    Posts
    64
    Rep Power
    5
    Hi salem,

    1) Do I have to use fflush (stdout); whenever I print something?

    2) I did not quite catch this:
    > scanf (" %f", &hrs);
    scanf returns a result, perhaps you should check it, and act accordingly.
    Last edited by kathyrollo; May 30th, 2013 at 09:48 AM.
  20. #11
  21. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,151
    Rep Power
    2222
    Originally Posted by kathyrollo
    Hi salem,

    1) Do I have to use fflush (stdout); whenever I print something?
    salem wrote:
    Originally Posted by salem
    You should follow this with fflush(stdout); to guarantee that the user will see the prompt before reading the input. The output stream is flushed automatically if the last char of printf is "\n".
    stdout is buffered. That means that when you write to it, you're actually writing to a buffer. At some future time, the contents of that buffer will be written out to the console and actually get displayed.

    Until the contents of the buffer are written to the console, the user will not be able to read them. If you want to ensure that the user will be able to read what you printf'd, you need to ensure that the contents of the buffer get written to the console.

    fflush(stdout) will force the buffer to be displayed. So will writing "\n" to the buffer.

    If you end the string with "\n", then you would not need to use fflush(stdout), as salem said.

    BTW, one debugging mistake made when a program crashes is to assume that if you don't see certain output displayed then the program never got to that line, hence that the crash happened before that line. Not necessarily. That output could very well have been written to the buffer, but then the program crashed before the buffer could be flushed. Adding an fflush after that line might help in the debugging process.


    Originally Posted by kathyrollo
    2) I did not quite catch this:
    > scanf (" %f", &hrs);
    scanf returns a result, perhaps you should check it, and act accordingly.
    Read the documentation for scanf (eg, Google on man page scanf. It will tell you what the return value of scanf is and what it means. Read that.

    But before you do, run your program. When it prompts you to enter the number of hours, input "four" (without the quotation marks, of course). Not "4", but rather spell it out as "four". What does your program do?

    I predict that your program will have a wildly weird value for hrs, something either hugely positive or hugely negative. Follow that scanf with a printf to echo back the value for hrs in order to verify what you get. The reason is because you gave scanf invalid input, so it did not perform the conversion and it left hrs with the value it previously contained. Since hrs is uninitialized, it starts out containing garbage and after that failed scanf call it will still contain that same garbage value.

    An old-time member of this forum had a favorite statement that with a few keystrokes he could send your program running off into the weeds to vomit on its own shoes. That is because your program needs to be able to deal with anything that the user might type.

    So how are you supposed to know whether the user provided scanf with valid input? Read about scanf's return value in the documentation.

    RTFM! ("Read The Manual!") It's not just for professionals.
  22. #12
  23. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Location
    Manila, Philippines
    Posts
    64
    Rep Power
    5
    So far guys, this is what I have:
    (Referred from this article.)
    Code:
    // Function for parking fee
    
    #include <stdio.h>
    #include <math.h>
    
    int main (void)
    {
    	float hrs;
    	
    	do
    	{
    		fputs ("Enter no. of hours: ", stdout);
    		fflush (stdout);
    		scanf (" %f", &hrs);
    		hrs = ceil (hrs);
    		if (hrs <= 0)
    		{
    			puts ("Your input is invalid!\n");
    		}
    	}
    	while (hrs <= 0);
    	
    	printf ("Your parking fee is: %.2f",
    		(hrs >= 3) ? ((10 * hrs) + 20) : (50));
    		
    	return 0;
    }
    I have been reading the scanf man page and I am still going about this question:
    So how are you supposed to know whether the user provided scanf with valid input?
    Thanks salem for the pointers and dwise1_aol for explaining stuff further.

IMN logo majestic logo threadwatch logo seochat tools logo