My task was to index a file in C.I'm getting one argument: file name. The index should contain all the words and a line list which appears in.A few notes:Big and small letters are the same.A word is max sequence of chars which are only from english alphabet and or digits every other char is splitting between the words.I should print an error message to stderr if I got too much args or if the input isn't matching (file doesn't exist).The output will be written to a file with the same name and the ending .index: if the file reading from is input.txt the output will be at input.txt.index.The word in the file should appear in lexicographic order.For example:input.txt:Hello worldMy, name isWoooW././.LByeSo the file input.txt.index is created and should contain:The word: bye             appears in line: 4The word: hello           appears in line: 1The word: is              appears in line: 2The word: l               appears in line: 3The word: my              appears in line: 2The word: name            appears in line: 2The word: wooow           appears in line: 3The word: world           appears in line: 1My code:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdbool.h>#include <ctype.h>#include index.h/* Text functions area */FILE *getFile (int argc, char const *argv[]) { /* A function to get the file inclouding a input check */    FILE *theinput;    if (argc < 2) { /* no argument */        fprintf(stderr, Must pass an argument!\n);        exit(1);    }    theinput = fopen(argv[1], r);    if (!theinput) { /* Argument is non-existing file */        fprintf(stderr, Can't read %s\n, argv[1]);        exit(1);    }    return theinput;}char *getText (FILE *file) { /* Gets the text from file, Return a string with the file content */    char *text, *q;    char token;    int i = 0;    text = malloc(sizeof(char));    while ((token = getc(file)) != EOF) {        text[i] = token;        i++;        q = realloc(text, (i + 2) * sizeof(char));        if (!q) {            fprintf(stderr, Out of memory\n);            exit(1);        }        text = q;    }    text[i] = '\0';    return text;}bool isLegalChar (char a) { /* Checks if a char is A - Z or a - z or 0 - 9 using ascii */    if (a <= 90 && a >= 65) { /* A = 65, Z = 90 */        return true;    }    else if (a <= 122 && a >= 97) { /* a = 97, z = 122 */        return true;    }    else if (isdigit(a)) {        return true;    }    else {        return false;    }}char *getWord (char *text, int start, bool *isEnterFound) { /* returns a single word from text starts searching from start */    char *word,*q; /* q = a helper string to make sure mallocing well */    char token; /* token is the right now input char */    int i = 0;    int j = start;    word = malloc(sizeof(char));    while (isLegalChar(token = text[j++]) || token == '\n') {         if (token == '\n')        {            (*isEnterFound) = true;            break;        }        word[i++] = token;        q = realloc(word, (strlen(word) + 2) * sizeof(char));        if (!q) {            fprintf(stderr, Out of memory\n);            exit(1);        }        word = q;    }    word[i] = '\0';    return word;}void tolowerString (char *input) { /* Changes a string so all the letters in it will by lower */    int i;    for (i = 0; i < strlen(input); ++i)    {        input[i] = tolower(input[i]);    }}char* stradd(const char* a, const char* b) { /* Return a string which is the two given strings combined */    size_t len = strlen(a) + strlen(b);    char *ret = (char*)malloc(len * sizeof(char) + 1);    *ret = '\0';    return strcat(strcat(ret, a) ,b);}/* Tree functions area */ Node* newNode(char* word, int line) { /* Return a new node with the vars given to the funcion */    Node *p = (Node*) malloc (sizeof(Node));     p->word = word;    p->lines = malloc(sizeof(int));    p->lines[0] = line;    p->linesLength = 1;    p->ls = p->rs = NULL;     return p; }void insert(Node **root, char *word, int line) { /* Insert node to tree using recursion */    int *q;    int i;    if(!*root) {        *root = newNode(word, line);         return;     }    if(strcmp(word, (*root)->word) < 0)  /* In case word is smaller than the nodes word */    {         insert(&((*root)->ls),word,line);     }    else if (strcmp(word, (*root)->word) == 0) /* In case word already exist */    {        for (i = 0; i < (*root)->linesLength; ++i)        {            if ((*root)->lines[i] == line)            {                return;            }        }        q = realloc((*root)->lines, (*root)->linesLength + 2);        if (!q)        {            fprintf(stderr, Out of memory!\n);            exit(1);        }        (*root)->lines = q;        (*root)->lines[(*root)->linesLength] = line;        (*root)->linesLength++;        return;    }    else /* In case word is bigger than the nodes word */    {        insert(&((*root)->rs),word,line);     }}void printTreeRec(Node *root, FILE *outputFile) { /* A recursive function which prints the tree by given root */    int i;    if(!root) {        return;     }    printTreeRec(root->ls, outputFile);    fprintf(outputFile, The word: \%s\ ,root->word);     if (strlen(root->word) < 15) {        for (i = 0; i < 15 - strlen(root->word); ++i) {            fprintf(outputFile,  );        }    }       fprintf(outputFile, appears in );    if (root->linesLength == 1) {        fprintf(outputFile, line: );    }    else {        fprintf(outputFile, lines: );    }    for (i = 0;i < root->linesLength - 1; i++) {        fprintf(outputFile, %d, , root->lines[i]);    }    fprintf(outputFile, %d, root->lines[i]);    fprintf(outputFile, \n);    printTreeRec(root->rs,outputFile);}void freeTree(Node *root) { /* A function to free the tree recursively */    if(!root)        return;     freeTree(root->ls);    freeTree(root->rs);     free(root->lines);    free(root); }/* Main */int main(int argc, char const *argv[]) {    FILE *inputFile = getFile(argc,argv); /* Opening input file */    char *ouputAddress = stradd(argv[1],.index); /* Creating output file address */    FILE *outputFile = fopen(ouputAddress,w); /* Creating output file */    char *text = getText(inputFile);    char *word;    int line = 1; /* Line counter */    bool foundEnter = false;    bool *isEnterFound = &foundEnter;    Node *root = NULL; /* First node of the tree */    int start = 0; /* Pointer to what was the last thing readed in text string */    while (start < strlen(text)) {        word = getWord(text, start, isEnterFound); /* If getWord detected enter foundEnter will become true */        tolowerString(word);        start += strlen(word) + 1;        if (strcmp(word, ) != 0) /* If word is not NULL */        {            insert(&root,word,line);        }        if (foundEnter)        {            foundEnter = false;            line++;        }    }    /* Ptinting the tree */    printTreeRec(root, outputFile);    /* Freeing the tree */    freeTree(root);    fclose(inputFile);    fclose(outputFile);    free(ouputAddress);    free(text);    free(word);    return 0;}It's working great, but I'm afraid of memory problems because of all the struct vars.By the way, the code is running at time complexity of \$O(log(n))\$, which is for adding a word to a binary search tree. 
Creating index to a file in C
c;file