So, as an exercise I wanted to make a simple binary tree as practice before moving on to other, harder things. I tried to implement a binary tree in a simple guessing game scenario. I can't test it due to issues I'm having with taking in input. But I can't reproduce the error in a smaller program, so I don't know what is going on.

testbinary.c:

//can't do default functions parameters in C
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

struct binary {
    unsigned long ID;
    char *guess;
    char isAns;
    struct binary *yes;
    struct binary *no;
};
typedef struct binary Node;

char * expstrcpy(char * a);
Node *getnew(char *msg, char isAns);
void push1(Node **old,Node *nnew,char yn);
void push2(Node **old,char *str,char yn);
void replace(Node **old, Node *nnew);
void pop(Node **pop,char yn);
void destroy_node(Node **a);
void destroy_branch(Node **del, int depth);
int isyes(char *a);
int isno(char *a);
void traverse(Node **top);

char * expstrcpy(char * a)
{
    char *b = malloc(sizeof(a));
    while(*b++ = *a++);
    return b;
}
Node * getnew(char *msg, char isAns)
{
    Node *nnew = malloc(sizeof(Node));
    nnew->ID=clock();
    nnew->guess=msg;
    isAns=isAns;
    nnew->yes=0;
    nnew->no=0;
    return nnew;
}
void push1(Node **old,Node *nnew,char yn)
{
    if(yn=='y')
        nnew->yes=*old;
    else
        nnew->no=*old;
    *old = nnew;
}
void push2(Node **old,char *str,char yn)
{
    Node *nnew = getnew(str,'n');
    if(yn=='y')
        nnew->yes=*old;
    else
        nnew->no=*old;
    *old = nnew;
}
void replace(Node **old, Node *nnew)
{
    Node *a = *old;
    nnew->yes=a->yes;
    nnew->no=a->no;
    free(a->guess);
    a->yes=0;
    a->no=0;
    *old = nnew;
    free(a);
}
void pop(Node **pop,char yn)
{
    Node *a = *pop;
    free(a->guess);
    if(yn=='y')
    {
        printf("In pop, calling destroy_branch on a->no\n");
        destroy_branch(&a->no,0);
        *pop=(*pop)->yes;
    }
    else
    {
        printf("In pop, calling destroy_branch on a->yes\n");
        destroy_branch(&a->yes,0);
        *pop=(*pop)->no;
    }
    a->yes=0;
    a->no=0;
    free(a);
}
void destroy_node(Node **a)
{
    if(*a)
    {
        if((*a)->yes)
            printf("destroy_node: Warning: a->yes may possibly point to valid memory\n");
        if((*a)->no)
            printf("destroy_node: Warning: a->no may possibly point to valid memory\n");
        free((*a)->guess);
        (*a)->yes=0;
        (*a)->no=0;
        free(*a);
        *a = 0;
    }
}
void destroy_branch(Node **del, int depth)
{
    if(*del)
    {
        fprintf(stdout, "In destroy_branch, ID: %lu, %i deep\n",(*del)->ID,depth);
        if((*del)->yes)
            destroy_branch(&(*del)->yes,depth+1);
        else
            destroy_node(&(*del)->yes);
        if((*del)->no)
            destroy_branch(&(*del)->no,depth+1);
        else
            destroy_node(&(*del)->no);
        fprintf(stdout, "destroy_branch, at depth: %i, destroying ID:%lu\n",depth,(*del)->ID);
        destroy_node(del);
    }
}
int isyes(char *a) { return ((a=="y")||(a=="yes")||(a=="1")||(a=="one")||(a=="yeah")||(a=="yea")); }
int isno(char *a) { return ((a=="n")||(a=="no")||(a=="0")||(a=="zero")||(a=="nope")||(a=="nay")); }
void traverse(Node **top)
{
    if(*top)
    {    
        char ans[128] = "ok";
        char ans2[128] = "ok";
        if((*top)->isAns=='y')
            fprintf(stdout,"Is it %s (y/n)? ",(*top)->guess);
        else
            fprintf(stdout,"%s (y/n)? ",(*top)->guess);
        fgets(ans,128,stdin);
        if((*top)->isAns=='y')
        {
            if(isyes(ans))
            {
                printf("Successful string of guesses!\n");
            }
            else
            {
                printf("Enter another question to figure out the difference: ");
                fgets(ans,128,stdin);
                printf("Enter the right answer: ");
                fgets(ans2,128,stdin);
                push1(top,getnew(ans,'n'),'n');
                (*top)->yes = getnew(ans2,'y');
            }
        }
        else
        {
            if(isyes(ans))
            {
                if((*top)->yes)
                    traverse(&(*top)->yes);
                else
                {
                    printf("Null node for top->yes\n");
                    printf("Enter an answer: ");
                    fgets(ans,128,stdin);
                    (*top)->yes=getnew(ans,'y');
                }
            }
            else
            {
                if((*top)->no)
                    traverse(&(*top)->no);
                else
                {
                    printf("Null node for top->no\n");
                    printf("Enter an answer: ");
                    fgets(ans,128,stdin);
                    (*top)->no=getnew(ans,'y');
                }
            }
        }
    }
    else /************** right here ***************/
    {
        char ques[128] = "ok";
        char ans[128] = "ok";
        printf("Node is null\n");
        printf("Put in a question and answer to yes condition\n");
        printf("Enter question: ");
        while(!fgets(ques,128,stdin));
        printf("Enter answer for yes condition: ");
        while(!fgets(ans,128,stdin));
        (*top) = getnew(ques,'n');
        (*top)->yes=getnew(ans,'y');
    }
    printf("\n\n");
}
int main()
{
    Node *top = 0;
    int choice=7;
    while(choice)
    {
        printf("What would you like to do?\n");
        printf("\n\t0 -- quit\n\t1 -- traverse tree\n\t2 -- delete tree\n\n:");
        scanf("%d",&choice);
        if(choice==1)
        {
            traverse(&top);
        }
        else if(choice==2)
        {
            printf("\nWill now destroy the tree from top node:\n\n");
            destroy_branch(&top,0);
        }
        else if((choice<0)||(choice>2))
        {
            printf("\nInvalid option\n");
        }
    }
    return 0;
}

output:

What would you like to do?

    0 -- quit
    1 -- traverse tree
    2 -- delete tree

:1
Node is null
Put in a question and answer to yes condition
Enter question: Enter answer for yes condition: what?

This works fine:

#include <stdio.h>
int main()
{
    char ques[128] = "ok";
    char ans[128] = "ok";
    printf("Node is null\n");
    printf("Put in a question and answer to yes condition\n");
    printf("Enter question: ");
    fgets(ques,128,stdin);
    printf("Enter answer for yes condition: ");
    fgets(ans,128,stdin);
    fprintf(stdout,"question received: %s\n",ques);
    fprintf(stdout,"answer received: %s\n",ans);
    return 0;
}

valgrind just tells me that after 1 run I leaked 40 bytes. So no help there really.

Recommended Answers

All 2 Replies

Thanks. That worked.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.