Thread: my get_line function

  1. #1
    Temporal Apparition qubit67's Avatar
    Join Date
    Jan 2007
    Posts
    85

    my get_line function

    this is my get_line function:
    Code:
    #define BUFFER_SIZE 1
    
    char *get_line(FILE *file) 
    {
    	FILE *fp = file;
    	
    	char *buffer;
    	int ch,  i=0;
    	unsigned int buffer_size = BUFFER_SIZE, new_buffer_size;
    
    	assert(buffer_size > 0);
    
    	buffer = (char *) malloc (buffer_size * sizeof (char));
    	
    	while ((ch = getc(fp)) != EOF && ch != '\n')
    	{
    		if (buffer_size == i) 
    		{
    			new_buffer_size = buffer_size * 2;
    			assert(new_buffer_size >= buffer_size);
    			buffer = (char *) realloc (buffer, new_buffer_size * sizeof (char));
    			buffer_size = new_buffer_size;
    		}
    		buffer[i] = ch;
    		i++;
    	}
    	if (ch == '\n')			 
    	{
    		buffer[i++] = '\0';
    		return buffer; 		/*finish it off with a null byte*/ 
    	}
    	if ((ch == EOF) && (i > 1))
    	{
    		buffer [i++] = '\0';
    		return buffer;
    	}
    	else
    	{
    		return NULL;
    	}
    }
    my questions are; does the i++ in the buffer need to be done or does the while loop update i when EOF or '\n' is encountered, and if the first input is the EOF, will NULL be returned as in the last statement?
    Last edited by qubit67; 09-08-2007 at 12:09 AM. Reason: p.s

  2. #2
    Temporal Apparition qubit67's Avatar
    Join Date
    Jan 2007
    Posts
    85
    im sorry, what do you mean?

  3. #3
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    sorry I just deleted it. I read it wrong. my fault.

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    > my questions are; does the i++ in the buffer need to be done

    No. At this point in the code i will not be used again and shouldn't need to be updated at all. As long as i is the biggest index in the array then you should place a '\0' correctly.

    Code:
    buffer = (char *) realloc (buffer, new_buffer_size * sizeof (char));
    
    ...
     
    else
    {
       return NULL;
    }
    These are some leaky and troublesome areas. You haven't thought about the need to free buffer if EOF is the first thing you see, or if realloc breaks so I recommend that you think about it now. Search the forum to see previous attempts at this idea.

    Have you considered reading more than one character from the start?

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    does the i++ in the buffer need to be done
    you mean in this?
    Code:
    buffer [i++] = '\0';
    no, it doesn't do anything since it's the post-increment operator and the i value isn't used any more.
    does the while loop update i when EOF or '\n' is encountered
    no. i is in the body, and if the loop condition fails, the loop body doesn't run.
    if the first input is the EOF, will NULL be returned as in the last statement?
    yes.

  6. #6
    Temporal Apparition qubit67's Avatar
    Join Date
    Jan 2007
    Posts
    85
    thanks for you input guys, will post the changed code when im finished

  7. #7
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Why dont u use just fgets to read a file?

    ssharish2005

  8. #8
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    With very little difficulty you could do something that the C++ version does and allow variation in the terminating character:

    Code:
    char *get_line( FILE *f, char ch='\n' ) {
      /* ... */
    }
    and change all the '\n' 's to ch.

  9. #9
    Temporal Apparition qubit67's Avatar
    Join Date
    Jan 2007
    Posts
    85
    Quote Originally Posted by ssharish2005 View Post
    Why dont u use just fgets to read a file?

    ssharish2005
    im not sure how to write a dynamic wrapper for it.

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by ssharish2005 View Post
    Why dont u use just fgets to read a file?
    fgets() takes a maximum length. The whole point of this get_line() function is to have no restriction on the length.

  11. #11
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Quote Originally Posted by brewbuck View Post
    fgets() takes a maximum length. The whole point of this get_line() function is to have no restriction on the length.
    My bad never read the whole post

    ssharish2005

  12. #12
    Temporal Apparition qubit67's Avatar
    Join Date
    Jan 2007
    Posts
    85
    so, I use getc and realloc with a dynamic buffer so the string has no size limitations. so far I have:
    Code:
    char *get_line(FILE *file) 
    {
    	FILE *fp = file;
    	
    	char *buffer;
    	int ch,  i=0;
    	unsigned int buffer_size = BUFFER_SIZE, new_buffer_size;
    
    	assert(buffer_size > 0);
    
    	buffer = (char *) safe_malloc (buffer_size * sizeof (char));
    	
    	while ((ch = getc(fp)) != EOF && ch != '\n')
    	{
    		if (buffer_size == i) 
    		{
    			new_buffer_size = buffer_size * 2;
    			assert(new_buffer_size >= buffer_size);
    			buffer = (char *) safe_realloc (buffer, new_buffer_size * sizeof (char));
    			buffer_size = new_buffer_size;
    		}
    		buffer[i] = ch;
    		i++;
    	}
    	if (ch == '\n')			 
    	{
    		buffer[i] = '\0';
    		return buffer; 		/*finish it off with a null byte*/ 
    	}
    	if ((ch == EOF) && (i >= 1))
    	{
    		buffer[i] = '\0';
    		return buffer;
    	}
    	else
    	{
                                    free (buffer);
    		return NULL;
    	}
    }
    There requirements of the function are :

    get_line reads a single line of text from its argument file pointer. If the EOF is encountered
    immediately without reading any characters from the file, the NULL pointer should be
    returned. Otherwise a pointer to a dynamically allocated string should be returned. The
    string must be large enough to fit an entire line of input. Lines are ended by the newline
    character, or when the EOF is encountered. Ending newline characters should be read in by
    the function, but they should NOT be stored in the string which is returned.

    My questions are:

    1. does my function fullful the requirements?

    2. is the guard of the while loop appropriate, or should I move the conditions : ch == EOF and ch == '\n' to the body of the loop with a break to end the loop then assign a null?

    3. In actuality, is this function correct, could it be modified to be better than it is?

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I would combine the end-criteria of EOF and newline - as you are doing exactly the same thing in two if-statements. This is generally not a good idea (because you'll be forgetting to change one side when you add something in the other, and then get strange behaviour sometimes).

    And your comment, which is a bit superfluous, about finishing off with a NUL-byte is on the wrong line.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  3. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  4. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  5. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM