I am trying to load words from a text file into a binary search tree

I am trying to load words from a text file into a binary search tree.

Each line of the file contains one word.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct node node;
struct node {
    node *left, *right;
    char *key;
};

node *newnode(char *key)
{
    node *n = malloc(sizeof(node));
    n->key = malloc(sizeof(key));
    strcpy(n->key, key);
    n->right = n->left = NULL;
    return n;
}

node *insirtNode(node *root, char *key)
{
    if (!root)
        return newnode(key);
    if (strcmp(key, root->key) < 0)
        root->left = insirtNode(root->left, key);
    else if (strcmp(key, root->key) > 0)
        root->right = insirtNode(root->right, key);
    return root;
}

void readFromFileToTree(const char *fname, node **root)
{ 
    // read each line
    FILE *s = fopen(fname, "r");
    if (!s) {
        printf("101");
        exit(0);
    }
    char *t = NULL;
    do {
        char temp[100];
        t = fgets(temp, 40, s); // printf("%s ",temp); to check what words are being insirting and whats not
        *root = (node *)insirtNode(*root, temp);
    } while (t);
    fclose(s);
}

int main()
{
    node *root = NULL;
    readFromFileToTree("anas.txt", &root);
    return 0;
}

the code stops before reading every word from the file
and returns -1073740940

>Solution :

The memory size allocated for the word in newnode() is incorrect: n->key = malloc(sizeof(key)); allocates the size of a pointer, not the length of the string plus an extra byte for the null terminator.

You should use strdup() that allocates and copies the string:

node *newnode(const char *key) {
    node *n = malloc(sizeof(node));
    n->key = strdup(key);
    n->right = n->left = NULL;
    return n;
}

Note also these problems:

  • printf("101"); is a cryptic error message. You should use

     fprintf(stderr, "cannot open %s: %s\n", fname, strerror(errno));
    

    and exit with a non-zero status;

  • the loop in readFromFileToTree() is incorrect: you will pass a null pointer to insirtNode() at the end of file. You should use this instead:

      char temp[100];
      while(fgets(temp, sizeof temp, s)) {
          *root = insirtNode(*root, temp);
      }
    

Here is a modified version:

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct node node;
struct node {
    node *left, *right;
    char *key;
};

node *newnode(const char *key) {
    node *n = malloc(sizeof(*n));
    n->right = n->left = NULL;
    n->key = strdup(key);
    return n;
}

node *insertNode(node *root, const char *key) {
    if (!root)
        return newnode(key);

    int cmp = strcmp(key, root->key);
    if (cmp < 0)
        root->left = insertNode(root->left, key);
    else
    if (cmp > 0)
        root->right = insertNode(root->right, key);
    return root;
}

node *readFromFileToTree(const char *fname) {
    node *root = NULL;
    FILE *fp = fopen(fname, "r");
    if (!fp) {
        fprintf(stderr, "cannot open %s: %s\n", fname, strerror(errno));
        return NULL;
    }
    char temp[100];
    while (fgets(temp, sizeof temp, fp)) {
        root = insertNode(root, temp);
    }
    fclose(fp);
    return root;
}

void freeTree(node *n) {
    if (n) {
        freeTree(n->left);
        freeTree(n->right);
        free(n);
    }
}

int main() {
    node *root = readFromFileToTree("anas.txt");
    freeTree(root);
    return 0;
}

Leave a Reply