Thread: Why is fgets not fully populating its buffer?

  1. #1
    Registered User
    Join Date
    Sep 2017
    Posts
    93

    Why is fgets not fully populating its buffer?

    Any ideas? I can't execute the clear buffer instruction because fgets never fully populates its buffer. If I execute the clear buffer functions before fgets populates its buffer, the clear buffer will go into an infinite loop since null is in stdin. It can't find '\n' or EOF.

    Why is fgets not fully populating its buffer?-cissues-jpg

  2. #2
    Registered User
    Join Date
    Sep 2017
    Posts
    93
    For example, if I place 10000 inside of the buffer, it's fully populated because of '\n' at the end.

    This isn't happening though for whatever reason.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Yes, post your code, not a fuzzy image.
    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.

  4. #4
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    "strlen(userInput) - 1" will never be 6, because userInput can hold at most 5 characters (6 with the null terminator).
    Devoted my life to programming...

  5. #5
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    You're still trying to use the length of the string to determine whether to clear the input buffer, which will not work.

    Check for the presence of the newline to determine if the entire input has been read. If the newline is present, everything has been read and no clearing is necessary. If no newline is present, there may be more input waiting on the buffer.

    This approach also allows you to replace the newline (if present) with '\0', thus eliminating it from the string.

    As I mentioned, this can be handled quite simply in its own function.

  6. #6
    Registered User
    Join Date
    Sep 2017
    Posts
    93
    Got it.

    Sorry, I'm difficult sometimes. :/

    Code:
    //
    //  main.c
    //  number_guess
    //
    //  Created by Joshua Ernzen on 12/20/17.
    //  Copyright © 2017 Joshua Ernzen. All rights reserved.
    //
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    static void stdinClear() {
        short int c;
        
        while((c = getchar()) != '\n' && c != EOF);
        
        return;
    }
    
    
    static int nonIntDetector(char *input, unsigned long stringLength, short int invalidInput) {
        short int inputCounter, intCounter, nonIntDetect, intDetect;
        char Numbers[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
        
        nonIntDetect = 0;
        intDetect = 0;
        
        if(invalidInput) {
            puts("Invalid input.");
            
            return 1;
        }
        
        for(inputCounter = 0; inputCounter < stringLength; inputCounter++)
            for(intCounter = 0; intCounter < 10; intCounter++) {
                if(input[inputCounter] == Numbers[intCounter]) {
                    intDetect++;
                    break;
                }
                if(intDetect != inputCounter) {
                    puts("Numbers only, please.");
                    
                    return 1;
                }
            }
        return nonIntDetect;
    }
    
    
    
    
    int main() {
        short int playAgain, loopChecker, randomNumber, intInput, invalidInput;
        char userInput[5], anotherGame[3];
        
        loopChecker = 1;
        
        puts("Random number guessing game.");
        
        do {
            randomNumber = arc4random_uniform(101);
            do {
                do {
                    invalidInput = 0;
                    printf("Enter your guess: ");
                    fgets(userInput, sizeof(userInput), stdin);
                    
                    if(strchr(userInput, '\n') == NULL) {
                        stdinClear();
                        invalidInput = 1;
                    }
                }
                while(nonIntDetector(userInput, strlen(userInput), invalidInput));
                
                intInput = atoi(userInput);
                
                if(intInput > randomNumber)
                    puts("Too High.");
                
                else if(intInput < randomNumber)
                    puts("Too low.");
            }
            while(intInput != randomNumber);
            
            puts("You win!");
            
            do {
                do {
                    invalidInput = 0;
                    
                    puts("Another game?");
                    puts("1. Yes, 2. No");
                    
                    fgets(anotherGame, sizeof(anotherGame), stdin);
                    
                    if(strchr(anotherGame, '\n') == NULL) {
                        stdinClear();
                        invalidInput = 1;
                    }
                }
                while(nonIntDetector(anotherGame, strlen(anotherGame), invalidInput));
                
                playAgain = atoi(anotherGame);
                
                if(playAgain == 2) {
                    playAgain = 0;
                    loopChecker = 0;
                }
                else if(playAgain == 1) {
                    loopChecker = 0;
                }
                else
                    loopChecker = 1;
            }
            while(loopChecker && puts("Invalid input."));
        }
        while(playAgain == 1);
        
        return 0;
    }

  7. #7
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Quote Originally Posted by ImageJPEG View Post
    Got it.

    Code:
    static void stdinClear() {
        short int c;
        
        while((c = getchar()) != '\n' && c != EOF);
        
        return;
    }
    getchar() returns an int, not short int. It doesn't make any practical difference on most systems, but it's more correct to use int. It's also less typing to write "int" than "short int".

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. fgets skipping, buffer issue?
    By TLW in forum C Programming
    Replies: 2
    Last Post: 02-20-2011, 08:15 PM
  2. Excess buffer using fgets
    By $l4xklynx in forum C Programming
    Replies: 20
    Last Post: 06-25-2009, 03:56 AM
  3. fgets buffer
    By Pythonsnake in forum C Programming
    Replies: 8
    Last Post: 01-11-2006, 12:27 AM
  4. Confused about fgets, clearing the buffer, etc
    By caduardo21 in forum C Programming
    Replies: 1
    Last Post: 06-13-2005, 11:03 AM
  5. fgets(buffer,sizeof(buffer),stdin);
    By linuxdude in forum C Programming
    Replies: 2
    Last Post: 10-28-2003, 10:41 AM

Tags for this Thread