cdata-structuresfile-processing

I can't seem to insert a node in a tree. Can someone take a look at my code and tell me where did I do wrong?


I've been trying to insert a node to my tree through file processing but it only always inserts one node then the program will force close itself. I have tried to put the data on a linkedlist and it worked. So probably the problem here is not the file.txt itself but my tree. Can someone tell me where did i do wrong?

Here is my tree algorithm

struct user {
    char username[50];
    int money;
    char favorite[50];
    user *left;
    user *right;
};

user *root = NULL;

user *userTree(char username[], int money, char favorite[]) {
    user *newBranch = (user *) malloc(sizeof(user));
    strcpy(newBranch->favorite, favorite);
    strcpy(newBranch->username, username);
    newBranch->money = money;
    return newBranch;
}

user *insertUser(user *root,char username[], int money, char favorite[]) {
    if (root == NULL) {
        return userTree(username ,money, favorite);
    }
    else if (strcmp(username, root->username) < 0) {
        root->left = insertUser(root->left, username, money, favorite);
    }
    else {
        root->right = insertUser(root->right, username, money, favorite);
    }
    return root;
}

Here is my file processing algorithm

void insertCredential() {
    FILE* fr = fopen("users/users.txt", "r");
    while (!feof(fr)) {
        char username[50], garbage[50], favorite[50];
        int money;
        fscanf(fr, "%[^#]#%[^#]#%d#%[^\n]\n", username, garbage, &money, favorite);
        root = insertUser(root, username, money, favorite);
        puts("test insert");
    }
    fclose(fr);
}

I have tried to put the data in a linked list and it worked but I want to know exactly why can't I insert it on a tree


Solution

  • At least these problems:

    1. code doesn't initialise left and right members after malloc(), leading to undefined behavior.. Consider calloc(). @trincot

    2. while (!feof(fr)) is wrong. @Andreas Wenzel. Check return value of fscanf().

    3. "%[^#]#%[^#]#%d#%[^\n]\n" lacks widths allowing input overruns. Add widths. "%49[^#]#%49[^#]#%d#%49[^\n]\n"

    4. Result of fopen() not checked.

    5. Allocation retuned pointer not checked for success.

    6. Code is not valid C. Looks like a C++ compiler used: user *root = NULL; --> struct user *root = NULL;. @Some programmer dude

    Weaknesses:

    1. money as an int may be too narrow. Consider long and a width: "%d" --> "%9ld".

    2. Cast not needed in newBranch = (user *) malloc(sizeof(user)); in C. Easier to maintain when the size referenced the object and not the type: newBranch = malloc(sizeof newBranch[0]);

    3. Greater applicability to use const for unchanged reference data: userTree(char username[], int money, char favorite[]) --> userTree(const char username[], int money, const char favorite[]).

    4. Trailing "\n" can read multiples white-spaces. Better error checking to use fgets() to read 1 line of line oriented data and then parse.