Thread: letters make my program explode

  1. #1
    Registered User
    Join Date
    Oct 2012
    Posts
    99

    letters make my program explode

    Can someone please tell me why Thanks!

    Code:
    int hours;
    float rate;
    float gross_pay;
    float net_pay;
    float taxes_were;
    
    printf("*******************************************************************\n");
    printf("Enter the number corresponding to the desired pay rate or action:\n");
    printf("1) $8.75/hr                         2) $9.33/hr\n");
    printf("3) $10.00/hr                        4) $11.20/hr\n");
    printf("5) quit\n");
    printf("******************************************************************\n");
    do{
        scanf("%f", &rate);
        printf("The number is %f\n", rate);
    
        if(!(rate<=5 && rate>=1))
            {
            printf("Invalid entry.   Please try again.\n");
            }
        else if(rate<=4 && rate>=1)
            {
            printf("How many hours did you work this week?\n");
            scanf("%i", &hours);
            gross_pay=total_pay(hours, rate);
            taxes_were=tax_bracket(gross_pay);
            net_pay=gross_pay-taxes_were;
            printf("Your gross pay was: %.2f\n", gross_pay);
            printf("Your taxes were:    %.2f\n", taxes_were);
            printf("Your net pay was:   %.2f\n", net_pay);
            }
        else
            {
            break;
            }
        printf("*******************************************************************\n");
        printf("Enter the number corresponding to the desired pay rate or action:\n");
        printf("1) $8.75/hr                         2) $9.33/hr\n");
        printf("3) $10.00/hr                        4) $11.20/hr\n");
        printf("5) quit\n");
        printf("******************************************************************\n");
    }while(1==1);
    
    printf("Quitting.  Goodbye!\n");
    return 0;
    }
    I think it has to do with the fact that a letter is obviously not a float, and the program expects a float. But it seems to me that my first "if" statement would simply take care of any letter that might be scanned into my "rate" variable? Thanks.

  2. #2
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Code:
    scanf("%i", &hours);
    This should be with %d, not with %i

    Code:
    while(1==1)
    replace with this
    Code:
    while(1)
    They are equivalent.

  3. #3
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    When scanf encounters a letter where should have been a digit, it leaves that letter in the input buffer, it doesn't remove it. You should check scanf's return value, which is the amount of successful reads, and if it's not what you expected ( in this case 1 ) then clear the input buffer and re scan for input.
    Devoted my life to programming...

  4. #4
    Registered User
    Join Date
    Oct 2012
    Posts
    99
    Quote Originally Posted by GReaper View Post
    When scanf encounters a letter where should have been a digit, it leaves that letter in the input buffer, it doesn't remove it. You should check scanf's return value, which is the amount of successful reads, and if it's not what you expected ( in this case 1 ) then clear the input buffer and re scan for input.
    Can you give me an example of how one clears the buffer? I think it's flush but I haven't got there yet in my textbook. (Teaching myself).

  5. #5
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Quote Originally Posted by gratiafide View Post
    Can you give me an example of how one clears the buffer? I think it's flush but I haven't got there yet in my textbook. (Teaching myself).
    No worries - FAQ > Flush the input buffer - Cprogramming.com
    Fact - Beethoven wrote his first symphony in C

  6. #6
    Registered User
    Join Date
    Oct 2012
    Posts
    99
    Quote Originally Posted by Click_here View Post
    After reading that, I don't see where the flushing is occurring. I'm guessing it's this line:
    Code:
      if (fgets(buf, sizeof(buf), stdin))
    but I don't understand how this flushes the input. Could someone expand a bit on this topic for me please? I guess "flushing" doesn't do the trick? Thanks.

  7. #7
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    It's the part that reads the input until '\n' or EOF is found

    Code:
    while ((ch = getchar()) != '\n' && ch != EOF);
    Fact - Beethoven wrote his first symphony in C

  8. #8
    Registered User
    Join Date
    Oct 2012
    Posts
    99
    Ok - Thanks.

    Also, I'm still having trouble getting my program to quit the loop if a character is entered. Here is what I currently have. It seems something is not working between my a=scanf and my else if( || ) statements.

    Code:
    int a;
    
    do{
    a=scanf("%f", &rate);
    if(!(rate<=5 && rate>=1)) {
    printf("Invalid entry. Please try again.\n");
    }
    else if(rate<=4 && rate>=1) { printf("How many hours did you work this week?\n"); scanf("%d", &hours);
    } else if(rate==5 || a==0) { break;
    }
    }while(1);

  9. #9
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by gratiafide View Post
    After reading that, I don't see where the flushing is occurring. I'm guessing it's this line:
    Code:
      if (fgets(buf, sizeof(buf), stdin))
    but I don't understand how this flushes the input. Could someone expand a bit on this topic for me please? I guess "flushing" doesn't do the trick? Thanks.
    fflush(NameOfStream) ;

    works ONLY for output streams - not input. Think of it like flushing your toilet - it works OK there, but you can't flush the kitchen faucet!

    Careful user input validation is not as trivial as it seems. One of the better plans is to take input as a string, and then check it over, before converting it to the numerical data you need with a function like strtoi().

    A single getchar() after a scanf() will remove that trailing newline char left over in the input buffer and stop the char exploding your program, when it expects a number to be entered.

    For any single char scanf(" %c", &YourCharVarHere), the single space before the %c is a BIG help, allowing scanf() to skip over newline chars as whitespace.

  10. #10
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by gratiafide View Post
    Code:
    int a;
    
    do{
        a=scanf("%f", &rate);
    
        f(!(rate<=5 && rate>=1))
    If scanf() encountered something other than a number, a will be zero (or EOF if end of input), and rate will be unmodified, i.e. its previous value.

    It does not make sense to check the value of rate if a is zero; so, you should check a first.

    In fact, I'd just do
    Code:
        if (scanf("%f", &rate) < 1) {
            printf("Invalid option. Exiting.\n");
            break;
        }
    or, if you want to skip invalid lines,
    Code:
        if (scanf("%f", &rate) < 1) {
            int c;
    
            /* Skip this line, until end of input or newline. */
            do {
                c = getchar();
            } while (c != EOF && c != '\n' && c != '\r');
    
            /* No more input? */
            if (c == EOF) {
                printf("No more input. Exiting.\n");
                break;
            }
    
            /* Complain about invalid option, then re-scan. */
            printf("What? Dude, just numbers, please.\n");
            continue;
        }
    Also, why don't you do the print just once, just before the scanf()? Seems pretty wasteful to duplicate printf() code like that.

  11. #11
    Registered User
    Join Date
    Oct 2012
    Posts
    99
    Quote Originally Posted by Nominal Animal View Post
    Also, why don't you do the print just once, just before the scanf()? Seems pretty wasteful to duplicate printf() code like that.
    I don't have all the code copied over, but what I left out is just some function calls that shouldn't affect the flow of my if statements. I think the answer to my problem may be in the buffer leftovers as Adak pointed out or in the fact that I am testing the "a" variable in the "else if" statement after I test "rate" as you pointed out. Perhaps the problem is both of these issues. Thanks for the tips, I found them helpful.

  12. #12
    Ticked and off
    Join Date
    Oct 2011
    Location
    La-la land
    Posts
    1,728
    Quote Originally Posted by gratiafide View Post
    I don't have all the code copied over
    No, I didn't mean that. After pointing out the issues in your code, the last line of my post was meant to tell you that here:
    Quote Originally Posted by gratiafide View Post
    Code:
    printf("*******************************************************************\n");
    printf("Enter the number corresponding to the desired pay rate or action:\n");
    printf("1) $8.75/hr                         2) $9.33/hr\n");
    printf("3) $10.00/hr                        4) $11.20/hr\n");
    printf("5) quit\n");
    printf("******************************************************************\n");
    do{
    
        some scanf() call
    
        /* SNIP */
    
        printf("*******************************************************************\n");
        printf("Enter the number corresponding to the desired pay rate or action:\n");
        printf("1) $8.75/hr                         2) $9.33/hr\n");
        printf("3) $10.00/hr                        4) $11.20/hr\n");
        printf("5) quit\n");
        printf("******************************************************************\n");
    }while(1==1);
    you needlessly duplicate the set of printf() commands. Just delete one set, and move the other set to the beginning of the loop body. The functionality stays the same, and you avoid duplicating the code.

  13. #13
    Registered User
    Join Date
    Oct 2012
    Posts
    99
    My bad. I get it now. Thanks. I originally had a while loop - but I was trying to find a way to get rid of the duplicate input statements. Thanks again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. loop needed also how to make input use letters
    By LoRdHSV1991 in forum C Programming
    Replies: 3
    Last Post: 01-13-2006, 05:39 AM
  2. Create something like php's explode()
    By phatsam in forum C Programming
    Replies: 6
    Last Post: 01-07-2006, 02:27 PM
  3. My head is going to explode.
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 20
    Last Post: 11-16-2003, 02:41 AM
  4. I'm about to explode
    By Lurker in forum A Brief History of Cprogramming.com
    Replies: 12
    Last Post: 11-11-2003, 05:44 AM
  5. Replies: 2
    Last Post: 03-25-2002, 05:49 AM