Thread: About scanf()

  1. #1
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216

    About scanf()

    It was once a bad headache for me. The C code like this:
    Code:
          while (gross != -1) {
               printf("input: ");
               scanf("%f", &gross);
          }
    When the code is compiled and executed, if input characters such as a, b, c, d...

    It'll become an infinite loop printing "input:". But yesterday, I found a

    solution to this all by chance. That is, change the code as follows:
    Code:
         while (gross != -1) {
              printf("input: ");
              scanf("%f", &gross);
              getchar(); /* Add getchar() here */
         }
    After adding 'getchar()' into the program, the infinite loop problem is solved.

    But I don't know why. Could you please tell me? And please tell me if there are

    other solutions to it. Thanks a lot.

    I also noticed that if any character is inputed, getchar() gets the

    character. If number is inputed, getchar() gets '\n'.
    I took advantage of this and wrote a small program, here is the code. Could

    you please give me some advice about my code? Thanks.

    Code:
    #include<stdio.h>
    
    #define BASE_PAY         200
    #define salary_cal(x)    9*(x)/100 + BASE_PAY
    
    int main()
    {
        float gross = 0.0;
        char  flag;
        
        while ( 1 ) {
            printf("Enter sales in dollars ( q to end ): ");
            scanf("%f", &gross);
            if ( ( flag = getchar() ) != '\n' ) {  /* If character is inputed */
                if ( flag == 'q' || flag == 'Q') { /* If 'q' or 'Q' is inputed, exit. */
                    printf("Thanks for using our product!\n");
                    return 0;
                }
                /* If the inputed character is not 'q' or 'Q' */
                printf("Invalid input!\n");
                continue;
            }
            printf("Salary: %.2f\n", salary_cal(gross) );
        }
    
        return 0;
    }

  2. #2
    ---
    Join Date
    May 2004
    Posts
    1,379
    '\n' is left in the input buffer after calling scanf
    calling getchar reads the '\n' and removing from the buffer.
    flush the buffer

  3. #3
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    >please give me some advice about my code?
    Read input as a string, then check for the 'q'; if not quitting, then attempt to convert the text to a float.
    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    #define BASE_PAY         200
    #define salary_cal(x)    (9*(x)/100 + BASE_PAY)
    
    int main()
    {
       while ( 1 )
       {
          char line[80];
          fputs("Enter sales in dollars ( q to end ): ", stdout);
          fflush(stdout);
          if ( fgets(line, sizeof line, stdin) )
          {
             float gross;
             if ( toupper((unsigned char)*line) == 'Q' )
             {
                break;
             }
             if ( sscanf(line, "%f", &gross) == 1 )
             {
                printf("Salary: %.2f\n", salary_cal(gross) );
             }
             else
             {
                puts("Invalid input!");
             }
          }
       }
       printf("Thanks for using our product!\n");
       return 0;
    }
    
    /* my output
    Enter sales in dollars ( q to end ): one thousand
    Invalid input!
    Enter sales in dollars ( q to end ): 1000
    Salary: 290.00
    Enter sales in dollars ( q to end ): q
    Thanks for using our product!
    */
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  4. #4
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216
    Thanks all for your kindly help.

    Dear Dave_Sinkula, thanks a lot, I learnt so much from your code.
    I found that without calling "fflush(stdout)", your program still run correctly, and exactly the same as fflush(stdout) is called, so I don't know why you call fflush(stdout) here. Is it neccessary to call fflush(stdout)? Could you please tell me?

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Without fflush(stdout): If the user inputs more than 80 characters, fgets() will read in the first 80 chars and leave the rest in the buffer. The loop will iterate again, and the remainder (ie, the chars beyond 80 chars) will be used the second time round.

    With fflush(stdout): If the user enters more than 80 chars, the excess chars are discarded.

    [EDIT]
    Ugh, the above only applies to fflush(stdin).

    For fflush(stdout), it's flushing the output stream.

    Was fflush(stdout) meant to be flush(stdin)?
    [/EDIT]

    (dave_sinkula, I think the code
    Code:
    fgets(line, sizeof line, stdin)
    should be
    Code:
    fgets(line, sizeof(line), stdin)

    )
    Last edited by dwks; 05-30-2005 at 08:21 PM.

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You do know that fflush only works on output streams, right? Any other use of it is undefined, which means nothing at all has to happen. If it does, it's purely implemenation specific. It could, and still be 100% ANSI conformant, crash whatever it's running on, and start a World War.


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by Antigloss
    I found that without calling "fflush(stdout)", your program still run correctly, and exactly the same as fflush(stdout) is called, so I don't know why you call fflush(stdout) here. Is it neccessary to call fflush(stdout)? Could you please tell me?
    http://www.eskimo.com/~scs/C-faq/q12.4.html

    In my preferred command shell, the prompts do not appear.
    Quote Originally Posted by dwks
    (dave_sinkula, I think the code
    Code:
    fgets(line, sizeof line, stdin)
    should be
    Code:
    fgets(line, sizeof(line), stdin)

    )
    The parentheses are only necessary for types; they are not necessary for objects and I prefer to write it that way.
    Last edited by Dave_Sinkula; 05-30-2005 at 09:26 PM. Reason: Typo.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  8. #8
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216
    Quote Originally Posted by quzah
    You do know that fflush only works on output streams, right? Any other use of it is undefined, which means nothing at all has to happen. If it does, it's purely implemenation specific. It could, and still be 100% ANSI conformant, crash whatever it's running on, and start a World War.


    Quzah.
    Do you mean that fflush(stdin) isn't standard C, and should never be used, or it'll lead to many unexpected problems?
    Last edited by Antigloss; 05-30-2005 at 09:33 PM.

  9. #9
    ---
    Join Date
    May 2004
    Posts
    1,379
    Quote Originally Posted by Antigloss
    Do you mean that fflush(stdin) isn't standard C, and should never be used, or it'll lead to many unexpected problems?
    Yes, it is in the FAQ.

  10. #10
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216
    Then, how to solve this problem?

    Quote Originally Posted by dwks
    If the user inputs more than 80 characters, fgets() will read in the first 80 chars and leave the rest in the buffer. The loop will iterate again, and the remainder (ie, the chars beyond 80 chars) will be used the second time round.

  11. #11
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216
    I found the answer in the FAQ.
    Thanks all~ ^_^

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. scanf() consideres useless
    By Snafuist in forum C Programming
    Replies: 15
    Last Post: 02-18-2009, 08:35 AM
  2. Help with a basic scanf procedure.
    By killpoppop in forum C Programming
    Replies: 9
    Last Post: 11-03-2008, 04:39 PM
  3. Replies: 2
    Last Post: 02-20-2005, 01:48 PM
  4. Scanf and integer...
    By penny in forum C Programming
    Replies: 3
    Last Post: 04-24-2003, 06:36 AM
  5. scanf - data is "put back" - screws up next scanf
    By voltson in forum C Programming
    Replies: 10
    Last Post: 10-14-2002, 04:34 AM