welsh_boy
asked on
Dealing with malloc'd structs
Hi guys, I am trying to code a game that tries to guess what object/animal/thing the user is thinking, i am using structs for the nodes in the tree.
Each struct has
a node number,
a nodetype,
a char array for an object & question - which can be empty,
a YES_ptr to another struct - which can be empty,
a NO_ptr to another struct - which can be empty,
When the game starts it checks whether the current node is an object or a question.
If it is an object it asks if the user was thinking of that object.
It it is a question, it asks that question, then according to the users response follows the appropriate pointer.
A restrictions
Please only use y and n for the answers, anything else wont work with the program at the moment.
My question is how to refer to the malloc'd nodes once they have been created.
E.g
When the program is first run it asks if you are thinking of a DOG?
If you say: n , And enter: e.g. a horse
it then asks for a question to distinguish between a horse and a dog
enter e.g. Does it gallop?
then it asks what is the answer for horse
enter y or n, it then sets the YES_ptr and NO_ptr for that question node appropriately.
This works fine for the first object you add.
Lets say now we are thinking of a lion
When you run it again it asks the previous question "Does it gallop?"
enter: n
it will ask if you are thinking of a DOG which is fine.
enter: n
It then asks what you were thinking
enter: lion
it then asks for a qeuestion to distinguish
e.g. enter : Does it have a main?
it then asks, what is the answer for a lion
if we enter: y (yes) it then sets the YES_ptr for that question to be lion, and it sets the NO_ptr to be Dog
but here i need to also change the previous question's (Does it gallop?) NO_ptr to this new question, and I am not sure how to refer to the previously malloc'd struct.
I hope you understand what I mean. If you run my prog you will see my problem.
Thanks
#include <stdio.h>
struct node
{
int nodetype; /*1 = question, 2 = object*/
int nodenumber;
char object[25];
char question[25];
struct node *YES_ptr;
struct node *NO_ptr;
};
int main()
{
struct node *new_ObjectNode, *current_node, *new_questionNode, dog;
char buffer[255], buffer1[255];
char *new_object1;
char user_input;
char *new_object, *new_question;
int nodecount = 1;
/* HARD CODE AN OBJECT NODE */
//struct node dog;
dog.nodetype = 2;
dog.nodenumber = 0;
dog.YES_ptr = NULL;
dog.NO_ptr = NULL;
strcpy(dog.object, "Dog");
//Allocate memory for the 2 new structs
new_ObjectNode = (struct node*)malloc (sizeof(struct node));
new_questionNode = (struct node*)malloc (sizeof(struct node));
printf("__________________ __________ __\n");
printf("| |\n");
printf("| GUESSING GAME |\n");
printf("| |\n");
printf("__________________ __________ __\n\n");
printf("Welcome to my game\nPlease thing of an object/animal/thing\n");
printf("__________________ __________ __\n");
//Set the current node to Dog when prog is first run
current_node= &dog;
//Outer loop for game
while (1)
{
//Inner loop for questions
while (1)
{
//If we are at a question node
if (current_node->nodetype == 1)
{
//ask the question
printf("%s \n", current_node->question);
fgetc(stdin);
//Get answer from user
scanf("%c", &user_input );
user_input = toupper( user_input );
//If answer is yes set current node to YES_ptr
if(user_input == 'Y'){
current_node = current_node->YES_ptr;
}
//If answer is no set current node to NO_ptr
if(user_input == 'N'){
current_node = current_node->NO_ptr;
}
}//if (question node)
if (current_node->nodetype == 2)
{ //Object Node
printf("Are you thinking of a %s?",current_node->object) ;
fflush(stdin);
scanf("%c", &user_input );
user_input = toupper( user_input );
if(user_input == 'Y')
{
printf("I win\n");
break; //Break out of the loop
}
if(user_input == 'N')
{
printf("You Win .....\n");
printf("What where you thinking?\n ");
//Enter new object and question into a new node
printf("Please Enter An Object \n");
fgetc(stdin);
new_object = fgets(buffer, 255, stdin);
printf("You have entered: %s\n", new_object);
memset(new_ObjectNode ->object, 0, 25);
memcpy(new_ObjectNode ->object, new_object,24);
new_ObjectNode ->nodetype = 2;
new_ObjectNode ->nodenumber = nodecount+1;
nodecount ++;
printf("Please Enter A Question \n");
new_question = fgets(buffer, 255, stdin);
memset(new_questionNode ->question, 0, 25);
memcpy(new_questionNode ->question, new_question,24);
new_questionNode ->nodetype = 1;
new_questionNode ->nodenumber = nodecount+1;
nodecount ++;
//Ask a question to distinguish between the new object and
//the current object
printf("Is the answer for %s Yes?",new_ObjectNode->obje ct);
scanf("%c", &user_input );
user_input = toupper( user_input );
//Set the question's pointers according to user answer
if(user_input == 'Y'){
new_questionNode ->YES_ptr = new_ObjectNode;
new_questionNode ->NO_ptr = current_node;
printf("Yes PTR: %s\n", new_questionNode->YES_ptr- >object);
printf("No PTR: %s\n", new_questionNode->NO_ptr-> object);
}
if(user_input == 'N'){
new_questionNode ->NO_ptr = new_ObjectNode;
new_questionNode ->YES_ptr = current_node;
printf("Yes PTR: %s\n", new_questionNode->YES_ptr- >object);
printf("No PTR: %s\n", new_questionNode->NO_ptr-> object);
}
//printf("Object You entered into struct is: %s \n", new_ObjectNode->object);
//printf("Question You entered into struct is: %s \n", new_questionNode->question );
//Set the current node to the new question node
current_node= new_questionNode;
break; //Break out of loop
} // (User input N)
else printf("\007Error: Invalid choice\n");
} // if (Object Node)
}
printf("Another Go?\n");
/*Get Response From User */
scanf(" %c", &user_input );
user_input = toupper( user_input );
/*If answer is No exit*/
if(user_input == 'N'){
printf("Thanks for playing\n");
break;
}
}
}
Each struct has
a node number,
a nodetype,
a char array for an object & question - which can be empty,
a YES_ptr to another struct - which can be empty,
a NO_ptr to another struct - which can be empty,
When the game starts it checks whether the current node is an object or a question.
If it is an object it asks if the user was thinking of that object.
It it is a question, it asks that question, then according to the users response follows the appropriate pointer.
A restrictions
Please only use y and n for the answers, anything else wont work with the program at the moment.
My question is how to refer to the malloc'd nodes once they have been created.
E.g
When the program is first run it asks if you are thinking of a DOG?
If you say: n , And enter: e.g. a horse
it then asks for a question to distinguish between a horse and a dog
enter e.g. Does it gallop?
then it asks what is the answer for horse
enter y or n, it then sets the YES_ptr and NO_ptr for that question node appropriately.
This works fine for the first object you add.
Lets say now we are thinking of a lion
When you run it again it asks the previous question "Does it gallop?"
enter: n
it will ask if you are thinking of a DOG which is fine.
enter: n
It then asks what you were thinking
enter: lion
it then asks for a qeuestion to distinguish
e.g. enter : Does it have a main?
it then asks, what is the answer for a lion
if we enter: y (yes) it then sets the YES_ptr for that question to be lion, and it sets the NO_ptr to be Dog
but here i need to also change the previous question's (Does it gallop?) NO_ptr to this new question, and I am not sure how to refer to the previously malloc'd struct.
I hope you understand what I mean. If you run my prog you will see my problem.
Thanks
#include <stdio.h>
struct node
{
int nodetype; /*1 = question, 2 = object*/
int nodenumber;
char object[25];
char question[25];
struct node *YES_ptr;
struct node *NO_ptr;
};
int main()
{
struct node *new_ObjectNode, *current_node, *new_questionNode, dog;
char buffer[255], buffer1[255];
char *new_object1;
char user_input;
char *new_object, *new_question;
int nodecount = 1;
/* HARD CODE AN OBJECT NODE */
//struct node dog;
dog.nodetype = 2;
dog.nodenumber = 0;
dog.YES_ptr = NULL;
dog.NO_ptr = NULL;
strcpy(dog.object, "Dog");
//Allocate memory for the 2 new structs
new_ObjectNode = (struct node*)malloc (sizeof(struct node));
new_questionNode = (struct node*)malloc (sizeof(struct node));
printf("__________________
printf("| |\n");
printf("| GUESSING GAME |\n");
printf("| |\n");
printf("__________________
printf("Welcome to my game\nPlease thing of an object/animal/thing\n");
printf("__________________
//Set the current node to Dog when prog is first run
current_node= &dog;
//Outer loop for game
while (1)
{
//Inner loop for questions
while (1)
{
//If we are at a question node
if (current_node->nodetype == 1)
{
//ask the question
printf("%s \n", current_node->question);
fgetc(stdin);
//Get answer from user
scanf("%c", &user_input );
user_input = toupper( user_input );
//If answer is yes set current node to YES_ptr
if(user_input == 'Y'){
current_node = current_node->YES_ptr;
}
//If answer is no set current node to NO_ptr
if(user_input == 'N'){
current_node = current_node->NO_ptr;
}
}//if (question node)
if (current_node->nodetype == 2)
{ //Object Node
printf("Are you thinking of a %s?",current_node->object)
fflush(stdin);
scanf("%c", &user_input );
user_input = toupper( user_input );
if(user_input == 'Y')
{
printf("I win\n");
break; //Break out of the loop
}
if(user_input == 'N')
{
printf("You Win .....\n");
printf("What where you thinking?\n ");
//Enter new object and question into a new node
printf("Please Enter An Object \n");
fgetc(stdin);
new_object = fgets(buffer, 255, stdin);
printf("You have entered: %s\n", new_object);
memset(new_ObjectNode ->object, 0, 25);
memcpy(new_ObjectNode ->object, new_object,24);
new_ObjectNode ->nodetype = 2;
new_ObjectNode ->nodenumber = nodecount+1;
nodecount ++;
printf("Please Enter A Question \n");
new_question = fgets(buffer, 255, stdin);
memset(new_questionNode ->question, 0, 25);
memcpy(new_questionNode ->question, new_question,24);
new_questionNode ->nodetype = 1;
new_questionNode ->nodenumber = nodecount+1;
nodecount ++;
//Ask a question to distinguish between the new object and
//the current object
printf("Is the answer for %s Yes?",new_ObjectNode->obje
scanf("%c", &user_input );
user_input = toupper( user_input );
//Set the question's pointers according to user answer
if(user_input == 'Y'){
new_questionNode ->YES_ptr = new_ObjectNode;
new_questionNode ->NO_ptr = current_node;
printf("Yes PTR: %s\n", new_questionNode->YES_ptr-
printf("No PTR: %s\n", new_questionNode->NO_ptr->
}
if(user_input == 'N'){
new_questionNode ->NO_ptr = new_ObjectNode;
new_questionNode ->YES_ptr = current_node;
printf("Yes PTR: %s\n", new_questionNode->YES_ptr-
printf("No PTR: %s\n", new_questionNode->NO_ptr->
}
//printf("Object You entered into struct is: %s \n", new_ObjectNode->object);
//printf("Question You entered into struct is: %s \n", new_questionNode->question
//Set the current node to the new question node
current_node= new_questionNode;
break; //Break out of loop
} // (User input N)
else printf("\007Error: Invalid choice\n");
} // if (Object Node)
}
printf("Another Go?\n");
/*Get Response From User */
scanf(" %c", &user_input );
user_input = toupper( user_input );
/*If answer is No exit*/
if(user_input == 'N'){
printf("Thanks for playing\n");
break;
}
}
}
ASKER
sorry about the indetation, it lost some of it when pasted in
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
#include <stdio.h>
struct node
{
int nodetype; /*1 = question, 2 = object*/
int nodenumber;
char object[25];
char question[25];
struct node *YES_ptr;
struct node *NO_ptr;
};
int main()
{
struct node *new_ObjectNode, *current_node, *new_questionNode, dog;
struct node *root_node;
char buffer[255], buffer1[255];
char *new_object1;
char user_input;
char *new_object, *new_question;
int nodecount = 1;
/* HARD CODE AN OBJECT NODE */
//struct node dog;
dog.nodetype = 2;
dog.nodenumber = 0;
dog.YES_ptr = NULL;
dog.NO_ptr = NULL;
strcpy(dog.object, "Dog");
//Allocate memory for the 2 new structs
printf("__________________ __________ __\n");
printf("| |\n");
printf("| GUESSING GAME |\n");
printf("| |\n");
printf("__________________ __________ __\n\n");
printf("Welcome to my game\nPlease thing of an object/animal/thing\n");
printf("__________________ __________ __\n");
//Set the current node to Dog when prog is first run
root_node= &dog;
//Outer loop for game
while (1)
{
//Inner loop for questions
current_node= root_node;
while (1)
{
//If we are at a question node
if( current_node->nodetype == 1 ){
//ask the question
printf("%s \n", current_node->question);
//fgetc(stdin);
//Get answer from user
scanf(" %c", &user_input );
user_input = toupper( user_input );
//If answer is yes set current node to YES_ptr
if( user_input == 'Y' ){
current_node = current_node->YES_ptr;
}
//If answer is no set current node to NO_ptr
if( user_input == 'N' ){
current_node = current_node->NO_ptr;
}
}//if (question node)
if( current_node->nodetype == 2 ){
//Object Node
printf("Are you thinking of a %s?",current_node->object) ;
fflush(stdin);
scanf(" %c", &user_input );
user_input = toupper( user_input );
if( user_input == 'Y' ){
printf("I win\n");
break; //Break out of the loop
}
if( user_input == 'N' ){
printf("You Win .....\n");
printf("What where you thinking?\n ");
//Enter new object and question into a new node
printf("Please Enter An Object \n");
fgetc(stdin);
new_object = fgets(buffer, 255, stdin);
printf("You have entered: %s\n", new_object);
new_ObjectNode = (struct node*)malloc (sizeof(struct node));
memset(new_ObjectNode ->object, 0, 25);
memcpy(new_ObjectNode ->object, new_object,24);
new_ObjectNode ->nodetype = 2;
new_ObjectNode ->nodenumber = nodecount+1;
nodecount ++;
printf("Please Enter A Question \n");
new_question = fgets(buffer, 255, stdin);
new_questionNode = (struct node*)malloc (sizeof(struct node));
memset(new_questionNode ->question, 0, 25);
memcpy(new_questionNode ->question, new_question,24);
new_questionNode ->nodetype = 1;
new_questionNode ->nodenumber = nodecount+1;
nodecount ++;
//Ask a question to distinguish between the new object and
//the current object
printf("Is the answer for %s Yes?",new_ObjectNode->obje ct);
scanf(" %c", &user_input );
user_input = toupper( user_input );
//Set the question's pointers according to user answer
if( user_input == 'Y' ){
new_questionNode ->YES_ptr = new_ObjectNode;
new_questionNode ->NO_ptr = root_node;
printf("Yes PTR: %s\n", new_questionNode->YES_ptr- >object);
printf("No PTR: %s\n", new_questionNode->NO_ptr-> object);
}
if( user_input == 'N' ){
new_questionNode ->NO_ptr = new_ObjectNode;
new_questionNode ->YES_ptr = root_node;
printf("Yes PTR: %s\n", new_questionNode->YES_ptr- >object);
printf("No PTR: %s\n", new_questionNode->NO_ptr-> object);
}
//printf("Object You entered into struct is: %s \n", new_ObjectNode->object);
//printf("Question You entered into struct is: %s \n", new_questionNode->question );
//Set the current node to the new question node
root_node= new_questionNode;
break; //Break out of loop
} // (User input N)
else printf("\007Error: Invalid choice\n");
} // if (Object Node)
}
printf("Another Go?\n");
/*Get Response From User */
scanf(" %c", &user_input );
user_input = toupper( user_input );
/*If answer is No exit*/
if( user_input == 'N' ){
printf("Thanks for playing\n");
break;
}
}
}
struct node
{
int nodetype; /*1 = question, 2 = object*/
int nodenumber;
char object[25];
char question[25];
struct node *YES_ptr;
struct node *NO_ptr;
};
int main()
{
struct node *new_ObjectNode, *current_node, *new_questionNode, dog;
struct node *root_node;
char buffer[255], buffer1[255];
char *new_object1;
char user_input;
char *new_object, *new_question;
int nodecount = 1;
/* HARD CODE AN OBJECT NODE */
//struct node dog;
dog.nodetype = 2;
dog.nodenumber = 0;
dog.YES_ptr = NULL;
dog.NO_ptr = NULL;
strcpy(dog.object, "Dog");
//Allocate memory for the 2 new structs
printf("__________________
printf("| |\n");
printf("| GUESSING GAME |\n");
printf("| |\n");
printf("__________________
printf("Welcome to my game\nPlease thing of an object/animal/thing\n");
printf("__________________
//Set the current node to Dog when prog is first run
root_node= &dog;
//Outer loop for game
while (1)
{
//Inner loop for questions
current_node= root_node;
while (1)
{
//If we are at a question node
if( current_node->nodetype == 1 ){
//ask the question
printf("%s \n", current_node->question);
//fgetc(stdin);
//Get answer from user
scanf(" %c", &user_input );
user_input = toupper( user_input );
//If answer is yes set current node to YES_ptr
if( user_input == 'Y' ){
current_node = current_node->YES_ptr;
}
//If answer is no set current node to NO_ptr
if( user_input == 'N' ){
current_node = current_node->NO_ptr;
}
}//if (question node)
if( current_node->nodetype == 2 ){
//Object Node
printf("Are you thinking of a %s?",current_node->object)
fflush(stdin);
scanf(" %c", &user_input );
user_input = toupper( user_input );
if( user_input == 'Y' ){
printf("I win\n");
break; //Break out of the loop
}
if( user_input == 'N' ){
printf("You Win .....\n");
printf("What where you thinking?\n ");
//Enter new object and question into a new node
printf("Please Enter An Object \n");
fgetc(stdin);
new_object = fgets(buffer, 255, stdin);
printf("You have entered: %s\n", new_object);
new_ObjectNode = (struct node*)malloc (sizeof(struct node));
memset(new_ObjectNode ->object, 0, 25);
memcpy(new_ObjectNode ->object, new_object,24);
new_ObjectNode ->nodetype = 2;
new_ObjectNode ->nodenumber = nodecount+1;
nodecount ++;
printf("Please Enter A Question \n");
new_question = fgets(buffer, 255, stdin);
new_questionNode = (struct node*)malloc (sizeof(struct node));
memset(new_questionNode ->question, 0, 25);
memcpy(new_questionNode ->question, new_question,24);
new_questionNode ->nodetype = 1;
new_questionNode ->nodenumber = nodecount+1;
nodecount ++;
//Ask a question to distinguish between the new object and
//the current object
printf("Is the answer for %s Yes?",new_ObjectNode->obje
scanf(" %c", &user_input );
user_input = toupper( user_input );
//Set the question's pointers according to user answer
if( user_input == 'Y' ){
new_questionNode ->YES_ptr = new_ObjectNode;
new_questionNode ->NO_ptr = root_node;
printf("Yes PTR: %s\n", new_questionNode->YES_ptr-
printf("No PTR: %s\n", new_questionNode->NO_ptr->
}
if( user_input == 'N' ){
new_questionNode ->NO_ptr = new_ObjectNode;
new_questionNode ->YES_ptr = root_node;
printf("Yes PTR: %s\n", new_questionNode->YES_ptr-
printf("No PTR: %s\n", new_questionNode->NO_ptr->
}
//printf("Object You entered into struct is: %s \n", new_ObjectNode->object);
//printf("Question You entered into struct is: %s \n", new_questionNode->question
//Set the current node to the new question node
root_node= new_questionNode;
break; //Break out of loop
} // (User input N)
else printf("\007Error: Invalid choice\n");
} // if (Object Node)
}
printf("Another Go?\n");
/*Get Response From User */
scanf(" %c", &user_input );
user_input = toupper( user_input );
/*If answer is No exit*/
if( user_input == 'N' ){
printf("Thanks for playing\n");
break;
}
}
}
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
thanks kent, I am trying your approach, here is my changed code.
I have changed it so that it sets the YES and NO ptrs depending on the users input from the question he has entered.
Trouble is that I am now getting a segmentation fault
:(
printf("Please Enter A Question \n");
new_question = fgets(buffer, 255, stdin);
struct node *NewNode = (struct node *)malloc (sizeof(struct node));
NewNode->nodenumber ==nodecount ++;
memcpy (NewNode, current_node, sizeof(struct node));
//Ask a question to distinguish between the new object and
//the current object
printf("What is the answer for %s?",new_ObjectNode->objec t);
scanf("%c", &user_input );
user_input = toupper( user_input );
//Set the question's pointers according to user answer
if(user_input == 'Y'){
current_node->YES_ptr = NewNode;
current_node->NO_ptr = new_ObjectNode;
current_node->nodetype = 1;
strcpy (current_node->question, buffer);
printf("Yes PTR: %s\n", current_node->YES_ptr->obj ect);
printf("No PTR: %s\n", new_questionNode->NO_ptr-> object);
} current_node
if(user_input == 'N'){
current_node->YES_ptr = new_ObjectNode;
current_node->NO_ptr = NewNode;
current_node->nodetype = 1;
strcpy (current_node->question, buffer);
printf("Yes PTR: %s\n", current_node->YES_ptr->obj ect);
printf("No PTR: %s\n", current_node->NO_ptr->obje ct);
}
//printf("Object You entered into struct is: %s \n", new_ObjectNode->object);
//printf("Question You entered into struct is: %s \n", new_questionNode->question );
//Set the current node to the new question node
//current_node= new_questionNode;
break; //Break out of loop
} // (User input N)
else printf("\007Error: Invalid choice\n");
} // if (Object Node)
I have changed it so that it sets the YES and NO ptrs depending on the users input from the question he has entered.
Trouble is that I am now getting a segmentation fault
:(
printf("Please Enter A Question \n");
new_question = fgets(buffer, 255, stdin);
struct node *NewNode = (struct node *)malloc (sizeof(struct node));
NewNode->nodenumber ==nodecount ++;
memcpy (NewNode, current_node, sizeof(struct node));
//Ask a question to distinguish between the new object and
//the current object
printf("What is the answer for %s?",new_ObjectNode->objec
scanf("%c", &user_input );
user_input = toupper( user_input );
//Set the question's pointers according to user answer
if(user_input == 'Y'){
current_node->YES_ptr = NewNode;
current_node->NO_ptr = new_ObjectNode;
current_node->nodetype = 1;
strcpy (current_node->question, buffer);
printf("Yes PTR: %s\n", current_node->YES_ptr->obj
printf("No PTR: %s\n", new_questionNode->NO_ptr->
} current_node
if(user_input == 'N'){
current_node->YES_ptr = new_ObjectNode;
current_node->NO_ptr = NewNode;
current_node->nodetype = 1;
strcpy (current_node->question, buffer);
printf("Yes PTR: %s\n", current_node->YES_ptr->obj
printf("No PTR: %s\n", current_node->NO_ptr->obje
}
//printf("Object You entered into struct is: %s \n", new_ObjectNode->object);
//printf("Question You entered into struct is: %s \n", new_questionNode->question
//Set the current node to the new question node
//current_node= new_questionNode;
break; //Break out of loop
} // (User input N)
else printf("\007Error: Invalid choice\n");
} // if (Object Node)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Your structure has fixed length buffers for both 'object' and 'question'. Is the question that you're asking short enough to fit in 24 character?
Other than that, it's hard to tell exactly where the segmentation fault is occurring. If you'll put a fflush(stdout); after each printf() we'll know the last print statement to get executed.
Kent
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
thanks Friedrich, and Kdo for all the help.
Will ask santa for a C book!! :)
Will ask santa for a C book!! :)
Hi welsh_boy,
Accepting an answer of "Go read a book" when you've got someone willingly assisting you defeats the spirit of these boards.
If you want to pursue this discussion, I'll be glad to continue walking you through the steps of finding and fixing the problems. Both with code recommendations and detailed explanations.
Kent
Accepting an answer of "Go read a book" when you've got someone willingly assisting you defeats the spirit of these boards.
If you want to pursue this discussion, I'll be glad to continue walking you through the steps of finding and fixing the problems. Both with code recommendations and detailed explanations.
Kent
ASKER