Thread: fgets in while loop

  1. #1
    Registered User
    Join Date
    Apr 2005
    Posts
    19

    fgets in while loop

    OK I know I've posted something like this before but I now have a slightly different problem.
    I am reading in input to a buffer line by line (using fgets) and then putting the buffer into an array of strings. I only need the first 100 elements (MAXBUF) of the array and so I cut it off with a null byte if it exceeds this.
    My problem is that next time it goes through the while loop, it doesn't prompt for input, but instead, the buffer is now equal to whatever was after the null byte I cut it off with.
    Am I missing something silly or is this how fgets works? I need to just discard anything after the cutoff null byte but can't seem to do it.
    Here's my code:
    Code:
     while( fgets( buf, MAXBUF, stdin ) != NULL && nel < MAX_ELEM )
            {
                    if (strlen(buf) >= MAXBUF)
                    {
                            buf[MAXBUF] = '\0';
                            printf("Buffer exceeds limit, snipping...\n");
                    }
                    data[nel] = (char*)malloc( (strlen(buf) + 1) * sizeof(char) );
                    assert( data[nel] != NULL );
                    strcpy( data[nel], buf );
                    nel++;          /* Count number of elements in array */
            }

  2. #2
    Registered User
    Join Date
    Apr 2004
    Posts
    173
    fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A '\0' is stored after the last character in the buffer.
    From the Linux man pages, so at most fgets() will read in BUFSIZ-1 in your case. It will also terminate the array for you so you don't need to mark it with a nul-byte character at the end. If the string is longer than BUFSIZ-1, then the characters after that will be discarded in the fgets() read.
    The cost of software maintenance increases with the square of the programmer's creativity.

  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
    > then the characters after that will be discarded in the fgets() read.
    No, they're left for the next call to fgets() to pick up.

    while ( fgets( buff, sizeof buff, in) ) fputs (buff,out);
    Will faithfully copy a text file irrespective of the size of your buffer.

    > if (strlen(buf) >= MAXBUF)
    The other bit was correct, this will never be true, so it's a waste of code.
    If you're trying to snip the newline from the end of the buffer, that's a different matter.

    > data[nel] = (char*)malloc( (strlen(buf) + 1) * sizeof(char) );
    Don't cast malloc in C (man, this sure is a frequent FAQ)

    > assert( data[nel] != NULL );
    Don't use assert for this. assert() is only present in debug code.
    Just because you compile in release mode won't stop malloc returning NULL.
    Also, assert() outside a debugger just causes the program to exit without warning, not the best idea if you're accumulating user input.
    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
    Registered User
    Join Date
    Apr 2004
    Posts
    173
    > then the characters after that will be discarded in the fgets() read.
    No, they're left for the next call to fgets() to pick up.
    Hmm maybe I didn't phrase it properly but I was referring to the "current" fgets() read - in that it omits any characters more than the size-1.
    The cost of software maintenance increases with the square of the programmer's creativity.

  5. #5
    Registered User
    Join Date
    Apr 2005
    Posts
    19
    Yeah that's what I thought, but when I run it through gdb, if I put a string longer than MAXBUF in, it WILL get cut-off automatically, but the next time the while loop comes around, instead of pausing for input again, it just loads whatever was left after the buf[MAXBUF] element into buf and uses that for some reason.

  6. #6
    Registered User
    Join Date
    Apr 2004
    Posts
    173
    The next call to fgets() will retrieve where it "left" off in this case since there is still input in the buffer, so it will just retrieve that data.

    Like:
    Code:
    #include <stdio.h>
    
    int main(void)
    {
            char temp[BUFSIZ];
    
            while((fgets(temp,5,stdin)) != NULL)
                    printf("%s\n",temp);
    
            return 0;
    }
    Sample output:
    Code:
    bash-3.00# ./fgets
    this is an example
    this
     is 
    an e
    xamp
    le
    The cost of software maintenance increases with the square of the programmer's creativity.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. fgets and breaking out of while loop
    By pollypocket4eva in forum C Programming
    Replies: 25
    Last Post: 01-05-2009, 06:50 PM
  2. Personal Program that is making me go wtf?
    By Submeg in forum C Programming
    Replies: 20
    Last Post: 06-27-2006, 12:13 AM
  3. A somewhat bizzare problem!!! - WHILE LOOP
    By bobthebullet990 in forum C Programming
    Replies: 3
    Last Post: 03-31-2006, 07:19 AM
  4. syntax question
    By cyph1e in forum C Programming
    Replies: 19
    Last Post: 03-31-2006, 12:59 AM
  5. when a while loop will stop ?
    By blue_gene in forum C Programming
    Replies: 13
    Last Post: 04-20-2004, 03:45 PM