Last active
June 11, 2024 12:22
-
-
Save aziyan99/178a858d57d755fe208d2fb1cbeb89e0 to your computer and use it in GitHub Desktop.
Simple POSIX getline() implementation in C using fgets()
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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