Reputation: 1369
First of all, I know this question is very close to this topic, but the question was so poorly worded that I am not even sure it is a duplicate plus no code were shown so I thought it deserved to be asked properly.
I am trying to read a file line by line and I need to store a line in particular in a variable
. I have managed to do so quite easily using fgets
, nevertheless the size of the lines to be read and the number of lines in the file remain unknown.
I need a way to properly allocate memory to the variable
whatever the size of the line might be, using C and not C++.
So far my code looks like that :
allowedMemory = malloc(sizeof(char[1501])); // Checks if enough memory
if (NULL == allowedMemory)
{
fprintf(stderr, "Not enough memory. \n");
exit(1);
}
else
char* res;
res = allowedMemory;
while(fgets(res, 1500, file)) // Iterate until end of file
{
if (res == theLineIWant) // Using strcmp instead of ==
return res;
}
The problem of this code is that it is not adaptable at all. I am looking for a way to allocate just enough memory to res
so that I don't miss any data in line
.
I was thinking about something like that :
while ( lineContainingKChar != LineContainingK+1Char) // meaning that the line has not been fully read
// And using strcmp instead of ==
realloc(lineContainingKChar, K + 100) // Adding memory
But I would need to iterate through two FILE
object in order to fill these variables which would not be very efficient.
Any hints about how to implement this solution or advise about how to do it in a easier way would be appreciated.
EDIT : Seems like using getline()
is the best way to do so because this function allocates the memory needed by itself and free it when needed. Nevertheless I don't think that it is 100% portable since I still can't use it though I have included <stdio.h>
. To be verified though, since my issues are often situated between keyboard and computer. Until then I am still open to a solution which would not use POSIX-compliant C.
Upvotes: 2
Views: 506
Reputation: 1
getline()
appears to do exactly what you want:
DESCRIPTION
The
getdelim()
function shall read from stream until it encounters a character matching the delimiter character....
The
getline()
function shall be equivalent to thegetdelim()
function with thedelimiter
character equal to the<newline>
character....
EXAMPLES
#include <stdio.h> #include <stdlib.h> int main(void) { FILE *fp; char *line = NULL; size_t len = 0; ssize_t read; fp = fopen("/etc/motd", "r"); if (fp == NULL) exit(1); while ((read = getline(&line, &len, fp)) != -1) { printf("Retrieved line of length %zu :\n", read); printf("%s", line); } if (ferror(fp)) { /* handle error */ } free(line); fclose(fp); return 0; }
And per the Linux man page:
DESCRIPTION
getline()
reads an entire line from stream, storing the address of the buffer containing the text into*lineptr
. The buffer is null- terminated and includes the newline character, if one was found.If
*lineptr
is set toNULL
and*n
is set 0 before the call, thengetline()
will allocate a buffer for storing the line. This buffer should be freed by the user program even ifgetline()
failed.Alternatively, before calling
getline()
,*lineptr
can contain a pointer to amalloc(3)
-allocated buffer*n
bytes in size. If the buffer is not large enough to hold the line,getline()
resizes it withrealloc(3)
, updating*lineptr
and*n
as necessary.In either case, on a successful call,
*lineptr
and*n
will be updated to reflect the buffer address and allocated size respectively.
Upvotes: 2