getdelim(), getline()

Updated: April 19, 2023

Read a delimited record from a stream

Synopsis:

#include <stdio.h>

ssize_t getdelim( char **restrict lineptr, 
                  size_t *restrict lenptr,
                  int delimiter,
                  FILE *restrict stream );

ssize_t getline( char **restrict lineptr, 
                 size_t *restrict lenptr,
                 FILE *restrict stream );

Arguments:

lineptr
A pointer to the address of a buffer for storing the read text. This argument can point to NULL if you want the function to allocate the buffer (see below).
lenptr
On input, a pointer to the current size, in bytes, of the buffer for storing the read text, if *lineptr is not NULL. On output, a pointer to the actual size of the buffer, which may be different (see below).
delimiter
(getdelim() only) The character to terminate reading when matched.
stream
The stream to read from.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The getdelim() function reads from stream until a character matching delimiter is encountered. The delimiter argument is an int, the value of which should be within the range of values covered by an unsigned char type. Otherwise, the delimiter character will not be matched.

The *lineptr argument should be a valid heap-allocated pointer that could be passed to the free() function. If *lenptr is non-zero, you should ensure that *lineptr either points to a buffer of at least *lenptr bytes or is a NULL pointer.

If *lineptr is a NULL pointer or the buffer it points to is too small, a buffer is allocated as if by malloc() or reallocated as if by realloc(). This way, the buffer is large enough to hold the characters to be written to it (including the terminating NUL), and *lenptr is set to the new size. If the buffer was allocated, or moved by the reallocation operation, *lineptr is updated to point to the new buffer or new location. The characters read, including any delimiter, are stored in the buffer, and a terminating NUL is added when the delimiter character or the end-of-file is encountered.

The getline() function is equivalent to the getdelim() function if the delimiter character equals the newline character.

Returns:

Note: Use feof() or ferror() to distinguish an end-of-file condition from an error.

Errors:

EINVAL
The lineptr or lenptr argument is a NULL pointer.
ENOMEM
There's insufficient available memory.
EOVERFLOW
The number of bytes to be written into the buffer (including the delimiter character if encountered) would exceed SSIZE_MAX.

Examples:

#include <stdio.h>
#include <stdlib.h>

int main( void )
{
  FILE     *fp;
  char     *line = NULL;
  size_t   len = 0;
  ssize_t  length;
  fp = fopen( "/etc/motd", NULL );
  if ( fp = NULL )
      exit ( 1 );
  while ( ( length = getline( &line, &len, fp ) ) != -1 ) {
      printf ( "Retrieved line of length %zd :\n", length );
      printf ( "%s", line );
  }
  if ( ferror( fp ) ) {
      /* handle error */
  }
  free( line );
  fclose( fp );
  return 0;
}

Classification:

POSIX 1003.1

Safety:  
Cancellation point Yes
Interrupt handler No
Signal handler Yes
Thread Yes