#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *input_f;
input_f = fopen("Input.txt", "r"); //Opens the file in read mode.
if (input_f != NULL)
{
char line[2048];
while( fgets(line, sizeof line, input_f) != NULL )
{
//do something
}
fclose(input_f); //Close the input file.
}
else
{
perror("File couldn't opened"); //Will print that file couldn't opened and why.
}
return 0;
}
Hi. I know I can read line by line with this code in C, but I don't want to limit line size, say like in this code with 2048.
I thought about using malloc, but I don't know the size of the line before I read it, so IMO it cannot be done.
Is there a way to not to limit line size?
This question is just for my curiosity, thank you.
Consider 2 thoughts:
An upper bound of allocated memory is reasonable. The nature of the task should have some idea of a maximum line length, be it 80, 1024 or 1 Mbyte.
With a clever OS, actual usage of allocated memory may not occur until needed. See Why is malloc not "using up" the memory on my computer?
So let code allocate 1 big buffer to limit pathological cases and let the underlying memory management (re-)allocate real memory as needed.
When you are allocating memory dynamically, you will want to change:
to
You read read up to (
maxl -1
) chars or anewline
(if usingfgetc
, etc..) or read the line and then check whetherline [strlen (line) - 1] == '\n'
to determine whether you read the entire line (if usingfgets
). (POSIX requires all lines terminate with anewline
) If you readmaxl
characters (fgetc
) or did not read the newline (fgets
), then it is a short read and more characters remain. Your choice is torealloc
(generally doubling the size) and try again. To realloc:Note: never reallocate using your original pointer (e.g.
line = realloc (line, 2 * maxl)
because ifrealloc
fails, the memory is freed and the pointer set toNULL
and you will lose any data that existed inline
. Also note thatmaxl
is typically doubled each time yourealloc
. However, you are free to choose whatever size increasing scheme you like. (If you are concerned about zeroing all new memory allocated, you can use memset to initialize the newly allocated space to zero/null. Useful in some situations where you want to insure yourline
is alwaysnull-terminated
)That is the basic dynamic allocation/reallocation scheme. Note you are reading until you read the complete line, so you will need to restructure your loop test. And lastly, since you allocated the memory, you are responsible for freeing the memory when you are done with it. A tool you cannot live without is
valgrind
(or similar memory checker) to confirm you are not leaking memory.Tip if you are reading and want to insure your string is always
null-terminated
, then after allocating your block of memory, zero (0
) all characters. As mentioned earlier,memset
is available, but if you choosecalloc
instead ofmalloc
it will zero the memory for you. However, onrealloc
the new space is NOT zero'ed either way, so callingmemset
is required regardless of what function originally allocated the block.Tip2 Look at the POSIX
getline
.getline
will handle the allocation/reallocation needed so long asline
is initialized toNULL
.getline
also returns the number of characters actually read dispensing with the need to callstrlen
afterfgets
to determine the same.Let me know if you have additional questions.