Break everything into smaller, more manageable functions. Here are my suggestions:
Code:
#include <stdint.h>
struct Phone
{
char* firstName;
char* lastName;
uint64_t number;
};
// Reads new phone book directory and saves it into "*ptr". Returns false if there are no more entries
bool readPhone(struct Phone* ptr, FILE* fptr);
// --- IN MAIN ---
struct Phone* book = NULL; // This holds all the structs
struct Phone temp; // Temporary for reading
while (readPhone(&temp, fptr)) {
// Expand book by means of realloc
// Assign temp to the last(not-used) index of the realloced array
}
// Profit!
// Loop through all of them and call free for firstName and lastName. If you want, you could define a function to do that for you.