cplus2java
asked on
problem implementing a stack (using character strings as data)
Hi,
I am trying to implement a stack (Last in ,first out). I enter
"To"
"Test"
"Ok"
but when I try to print, instead of printing "Ok", "Test" and "To"
I get "Ok", "Ok", "Ok". It seems word (after calling gets(word)) address remains same for all iterations
Can anyone help me fix the code ?. Attached is the code
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
struct ListNode;
struct ListNode * newList ( );
struct ListNode * cons (char *, struct ListNode *);
void print (struct ListNode *);
struct ListNode
{
char *name; /* points to the name */
struct ListNode *next; /*next list */
};
/* Return an empty linked list. */
struct ListNode * newList ( ) {
return 0;
}
/* Return the result of adding the given string to the front of the given list. */
struct ListNode * cons (char *s, struct ListNode * list) {
struct ListNode *newnode;
newnode =(struct ListNode *) malloc(sizeof(ListNode)) ; //allocate memory from heap
newnode->name =s; // point the name to the new string
newnode->next =list; // set next pointer to list;
return newnode;
}
/* Print the names in the given linked list, one per line. */
void print (struct ListNode * list) {
if( list!= 0) {
printf ("%s\n", list->name);
print ((list->next));
}
// TEST PROGRAM TO TEST STACK
int main ( ) {
char word[100];
printf ("Collecting names into a list.\n");
struct ListNode * list = newList ( );
while (gets(word)) {
//printf("%lu\n", word);
list = cons (word, list);
}
printf ("Printing the names in the list.\n");
print(list);
// print (&list);
return 0;
}
I am trying to implement a stack (Last in ,first out). I enter
"To"
"Test"
"Ok"
but when I try to print, instead of printing "Ok", "Test" and "To"
I get "Ok", "Ok", "Ok". It seems word (after calling gets(word)) address remains same for all iterations
Can anyone help me fix the code ?. Attached is the code
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
struct ListNode;
struct ListNode * newList ( );
struct ListNode * cons (char *, struct ListNode *);
void print (struct ListNode *);
struct ListNode
{
char *name; /* points to the name */
struct ListNode *next; /*next list */
};
/* Return an empty linked list. */
struct ListNode * newList ( ) {
return 0;
}
/* Return the result of adding the given string to the front of the given list. */
struct ListNode * cons (char *s, struct ListNode * list) {
struct ListNode *newnode;
newnode =(struct ListNode *) malloc(sizeof(ListNode)) ; //allocate memory from heap
newnode->name =s; // point the name to the new string
newnode->next =list; // set next pointer to list;
return newnode;
}
/* Print the names in the given linked list, one per line. */
void print (struct ListNode * list) {
if( list!= 0) {
printf ("%s\n", list->name);
print ((list->next));
}
// TEST PROGRAM TO TEST STACK
int main ( ) {
char word[100];
printf ("Collecting names into a list.\n");
struct ListNode * list = newList ( );
while (gets(word)) {
//printf("%lu\n", word);
list = cons (word, list);
}
printf ("Printing the names in the list.\n");
print(list);
// print (&list);
return 0;
}
Each of you list nodes is POINTING to the char word[100] array, so each and every node will "contain" the string that's in the word buffer, i.e. the last string entered.
When you create a new node, you need to allocate memory and copy the the string, so that each node has a unique copy of it's string.
When you create a new node, you need to allocate memory and copy the the string, so that each node has a unique copy of it's string.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
You don't allocate any string space in your list - all the strings point to only one place - the variable word!
Change your cons function as follows:
struct ListNode * cons (char *s, struct ListNode * list) {
struct ListNode *newnode;
newnode =(struct ListNode *) malloc(sizeof(ListNode)) ; //allocate memory from heap
/*MALLOC string space, copy string to that new space using strcpy *?
newnode->name = (char *)malloc(strlen(s)+1);
strcpy(newnode->name,s); // point the name to the new string
newnode->next =list; // set next pointer to list;
return newnode;
}
Change your cons function as follows:
struct ListNode * cons (char *s, struct ListNode * list) {
struct ListNode *newnode;
newnode =(struct ListNode *) malloc(sizeof(ListNode)) ; //allocate memory from heap
/*MALLOC string space, copy string to that new space using strcpy *?
newnode->name = (char *)malloc(strlen(s)+1);
strcpy(newnode->name,s); // point the name to the new string
newnode->next =list; // set next pointer to list;
return newnode;
}
sorry posternb,
took me too long to type... <grin>
BTW, sizeof(char) is redundant - by definition, it is always 1. Doesn't hurt, but it is not needed.
took me too long to type... <grin>
BTW, sizeof(char) is redundant - by definition, it is always 1. Doesn't hurt, but it is not needed.
Yes I know, I think it's good to be explicit for clarity though -- especially if, for example, someone copies the code and changes them it 'int'... you might forget it...
er to 'int'
ASKER
That definitely makes a lot of sense. Thanks for your help.
You should accept posternb's answer and not leave this question open...
ASKER