I do not if this is a good ,or even more, an implementable idea.Let me give you an idea,not ideal and not efficient but i think it will be a good lesson for how malloc works
Maybe a combination of malloc and realloc is the answer here.Declare an array of char pointers.Give it a logical size for start,that is going to be filled up for 80% at least in all cases(i mean for every data that the .txt file has).Every cell will host a string that is found at every loop.The memory for this string should be allocated by you,with malloc!
When the array fills up,use realloc to increase it's size by say 50% of the size,or even smarter think a way that will be analogous to the point of file that you are know in order to make the minimum increments of size,which of course is costly(if you would like i can explain why
).For example if you are two lines before EOF it wouldn't be so smart to increase the size of the array with the same factor you did when you were at the 1/6 of the file for example.Well you could first implement it with increasing size always by 50% and then do it more efficiently.
Then ,when you are done ,this array will hold in every cell the strings you found.Every cell will have a pointer that will point to a string.Remember that this space for the strings has to be allocated by you with malloc.
Then when you are done you have to free your memory.Do not do the same mistake to just free the array(which you can have allocated with realloc).First free the memory that you allocated for every string and then free the array.Do these operations as i said and not in reverse,because if you first free the array then you won't have access to the where the strings are!
PS- yes i know these is challenging and has a factor of difficulty