Skip to content

Instantly share code, notes, and snippets.

@aziyan99
Last active June 11, 2024 12:22
Show Gist options
  • Save aziyan99/178a858d57d755fe208d2fb1cbeb89e0 to your computer and use it in GitHub Desktop.
Save aziyan99/178a858d57d755fe208d2fb1cbeb89e0 to your computer and use it in GitHub Desktop.
Simple POSIX getline() implementation in C using fgets()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
ssize_t getline(char **restrict lineptr, size_t *restrict n, FILE *restrict stream)
{
// check if either lineptr or n are NULL pointers
if (lineptr == NULL || n == NULL)
{
fputs("Error! Bad arguments.\n", stderr);
return -1;
}
// check if stream is valid pointer
if (stream == NULL)
{
fputs("Error! Bad stream pointer.\n", stderr);
return -1;
}
// use chunk array of 128 bytes as parameters for fgets()
char chunk[128];
// allocate block of memory for *lineptr if it is NULL
if (*lineptr == NULL)
{
*n = sizeof(chunk);
*lineptr = malloc(*n);
if (*lineptr == NULL)
{
fputs("Error! Unable to allocate memory for lineptr buffer.\n", stderr);
return -1;
}
}
(*lineptr)[0] = '\0';
while (fgets(chunk, sizeof(chunk), stream))
{
// resize the *lineptr buffer if necessary
if (*n - strlen(*lineptr) < sizeof(chunk))
{
*n *= 2;
*lineptr = realloc(*lineptr, *n);
if (*lineptr == NULL)
{
fputs("Error! Unable to reallocate memory for lineptr buffer.\n", stderr);
free(lineptr);
return -1;
}
}
// append the chunk to the end of the *lineptr buffer
strcat(*lineptr, chunk);
// check if *lineptr contains '\n', if yes then return the *lineptr length
if ((*lineptr)[strlen(*lineptr) - 1] == '\n')
{
return strlen(*lineptr);
}
}
// return error
return -1;
}
int main(void)
{
FILE *fp;
char *line;
size_t len;
fp = fopen("./sample.txt", "r");
line = NULL;
len = 0;
if (fp == NULL)
{
printf("Error! Unable to open the provided file.\n");
exit(EXIT_FAILURE);
}
while (getline(&line, &len, fp) != -1)
{
printf("Line: '%s'\n", line);
}
fclose(fp);
return 1;
}
Foo Bar Bazz
Bar Bazz Foo
Bazz Foo Bar
Foo Bar Bazz
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment