Thread: fgets and scanf - couldn't diagnose new line bug.

  1. #1
    Registered User
    Join Date
    Dec 2011
    Posts
    3

    fgets and scanf - couldn't diagnose new line bug.

    hi,
    the following code generates the newline bug. Please help.


    Code:
    #include <stdio.h>
    
    
    int main (int argc, const char * argv[])
    {
        /*Village Administration Database
        fields 
        1. Name 
        2. Age 
        3. Sex
        */
        char name[1000][100];
        int age[1000];
        char sex;
        int gender;// boolean to verify gender
        int count = 0;
        
        // WELCOME
        
        fputs("WELCOME : Voters list Database\n",stdout);
        fputs("You can enter details of of 1000 voters(MAX)\n",stdout);
        
        for(;;)
        {
            
            printf("Please enter the details of Voter %d:",count+1);
        // NAME INPUT
        
        printf("Please enter the Name of the Voter :");
        fflush(stdin);
        fgets(name[count],100,stdin);
        
        
        // AGE INPUT
        
        fputs("Please enter the age of the Voter :", stdout);
        fflush(stdin);
        scanf(" %d",&age[count]);
    
    
        // SEX INPUT
        for(;;)
        {
            puts("Please enter Gender('M' for Male or 'F' for Female):");
            fflush(stdin);
            scanf(" %c",&sex);
            if(sex == 'm'|| sex=='f')
                break;
            {
                printf("ERROR!!!\nOnly 'M' or 'F' allowed\n ");
            }
        }
        gender = sex == 'm';
        
        //COUNT INCREMENT and CHECKING LIMIT
        count = count + 1;
        if(count == 999)
        {
            puts("YOU HAVE REACHED THE LIMIT OF ENTRIES");
            break;
        }
    }
        
        // OUTPUT
        
        printf("NAME: %s",name[count]);
        printf("AGE: %d\n",age[count]);
        if(gender)
            printf("GENDER : MALE");
        else
            printf("GENDER : FEMALE");
        
        return 0;
    }
    BUG:

    WELCOME : Voters list Database
    You can enter details of of 1000 voters(MAX)
    Please enter the details of Voter 1:Please enter the Name of the Voter :sandeep
    Please enter the age of the Voter :29
    Please enter Gender('M' for Male or 'F' for Female):
    m
    Please enter the details of Voter 2:Please enter the Name of the Voter :Please enter the age of the Voter :

    ---------------------------

    On the second time around the loop, the program wouldn't stop for the name input.

    please help... thanks in advance

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    fflush(stdin) is not good

    The problem is that you're hitting the enter key after you enter the gender, so your program sees "m\n". That '\n' is not read by %c (it only sees the 'm'), so the '\n' is eaten by fgets(). There have probably been about a million threads on this topic, so you could search the forum. Basically, don't mix scanf() and fgets(), but if you have to, it's up to you to get rid of unwanted newline characters. fflush(stdin) is not the way to do this (although it might work on some weird platforms).

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Stop using for loops with no loop control and putting a break inside. It's hard to read and error prone. Use a them the way they were intended:
    Code:
    #define MAX_ENTRIES 1000  // constants are way better than magic numbers
    #define MAX_NAME  100
    ...
        char name[MAX_ENTRIES][MAX_NAME];
        int age[MAX_ENTRIES];
    
        for (count = 0; count < MAX_ENTRIES; count++) {
            ...
        }
    You can't fflush(stdin), it results in undefined behavior. You can only flush output streams, but you don't need to do that in your program. Read this link for details. Read this link for other ways to clear the input buffer.

    When reading the sex of the voter, use a do while loop. Do while loops are great for user input because they always run once, so you always ask the user for input once and read input once, and only repeat if they screw up:
    Code:
    do {
        print "enter gender"
        read sex
    } while (tolower(sex) != 'm' && tolower(sex) != 'f');
    Note that I used tolower to convert the input before checking. That way, if the user inputs an uppercase M or F (as your prompt suggests), your program will still work.

    Lastly, the reason it doesn't ask for the name the second time around is because after they input the gender and press the enter key, there is a newline left in the input buffer. The second time through, fgets reads from the input buffer to the first new line, which is the first character, so it doesn't read a name. This demonstrates perfectly that your fflush(stdin) call doesn't work. You need to flush it in an appropriate manner.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. fgets and scanf
    By kkk in forum C Programming
    Replies: 10
    Last Post: 07-29-2011, 10:11 AM
  2. scanf vs fgets?
    By Matus in forum C Programming
    Replies: 65
    Last Post: 11-17-2008, 04:02 PM
  3. Is it conflict between scanf and fgets
    By alokdotnet in forum C Programming
    Replies: 10
    Last Post: 08-19-2006, 12:50 AM
  4. what happens after 'fgets' and 'scanf'
    By the bassinvader in forum C Programming
    Replies: 4
    Last Post: 07-30-2006, 03:04 PM
  5. Scanf->Fgets
    By 00Sven in forum C Programming
    Replies: 2
    Last Post: 04-21-2006, 02:39 PM