FGETLN(3)
π
FGETLN(3) β ok so this is the fgetln girlies' moment β¨
Welcome to the fgetln page, bestie β it's a libc classic from the Debian crew and I'm obsessed. Let's get into it π«Ά
π NAME π
fgetln β get a line from a stream. That's it. That's the whole vibe.
π LIBRARY π
Standard C Library (libc, -lc). The og. The blueprint. π
β¨ SYNOPSIS β¨
#include <stdio.h>
char *
fgetln(FILE *stream, size_t *len);
πΈ DESCRIPTION πΈ
Okay so fgetln() hands you back a pointer to the next line from the stream that stream points at. Cute, right? But here's the thing, and this is important, so listen up π₯:
- This line is not a C string β it does not end with a terminating
NULcharacter. Not me having to say this, but the function literally does not do it. π - The length of the line β including the final newline β gets stored in the memory location that
lenpoints to. - Small caveat bestie: if the line is the last line in a file that does not end in a newline, then the text you get back will not contain a newline either. The more you know π
π RETURN VALUES π
On success, you get a pointer back π β but lowkey this pointer is on a timer: it becomes invalid after the next I/O operation on stream (whether that op succeeded or not), or as soon as the stream is closed. So use it while it's fresh, iykyk.
Otherwise, NULL is returned. And here's the tragic part: fgetln() does not distinguish between end-of-file and error π. You have to call feof(3) and ferror(3) yourself to figure out which one actually happened. If an error occurs, the global variable errno gets set to indicate the error.
Also β the end-of-file condition is remembered, even on a terminal, and all subsequent attempts to read will return NULL until the condition is cleared with clearerr(3). She holds grudges. Periodt.
Now, the text the returned pointer points to may be modified, as long as you don't make changes beyond the returned size. But those changes are lost as soon as the pointer becomes invalid. So don't get attached π
π ERRORS π
[EBADF]β the argumentstreamis not a stream open for reading. Girl is closed for business.[ENOMEM]β the internal line buffer could not be expanded due to lack of available memory, or because it would need to expand beyondINT_MAXin size. She's ambitious but not that ambitious.
fgetln() may also fail and set errno for any of the errors specified for the routines fflush(3), malloc(3), read(2), stat(2), or realloc(3). Whole friend group of failure modes fr fr.
π¦ SEE ALSO π¦
ferror(3), fgets(3), fgetwln(3), fopen(3), getline(3), putc(3) β go read those too, they're all icons in their own right π
π§ HISTORY π§
The fgetln() function first appeared in 4.4BSD. Vintage. Main character energy since day one π
π CAVEATS π
So since the returned buffer is not a C string (it is not NUL terminated), the common practice is to replace the newline character with '\0'. Slay, that works. BUT β and this is the plot twist β if the last line in a file does not contain a newline, the returned text won't contain a newline either π so there's nothing to replace and you're standing there like π§
The following code demonstrates how to deal with this problem by allocating a temporary buffer:
char *buf, *lbuf;
size_t len;
lbuf = NULL;
while ((buf = fgetln(fp, &len)) != NULL) {
if (buf[len - 1] == '\n')
buf[len - 1] = '\0';
else {
/* EOF without EOL, copy and add the NUL */
if ((lbuf = malloc(len + 1)) == NULL)
err(1, NULL);
memcpy(lbuf, buf, len);
lbuf[len] = '\0';
buf = lbuf;
}
printf("%s\n", buf);
}
free(lbuf);
if (ferror(fp))
err(1, "fgetln");
Don't forget the free(lbuf) at the end, bestie β leaking memory is not the aesthetic π
And that's the page! This lil beauty comes to you from Debian, dated June 11, 2020 β a whole era. Stay hydrated, close your streams, and always check ferror ππ¦β¨
π¦ where this page comes from
- freebsd 15.1: base 15.1
- Copyright (c) 1990, 1991, 1993 The Regents of the University of California. All rights reserved
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms