Welcome to Dream.In.Code
Become a C++ Expert!

Join 149,556 C++ Programmers for FREE! Get instant access to thousands of C++ experts, tutorials, code snippets, and more! There are 1,613 people online right now. Registration is fast and FREE... Join Now!




help w/ PrintStack in C

2 Pages V  1 2 >  
Reply to this topicStart new topic

help w/ PrintStack in C

P4wn4g3
23 Nov, 2007 - 09:40 AM
Post #1

New D.I.C Head
*

Joined: 22 Nov, 2007
Posts: 12


My Contributions
K, so I am doing a programming project, requiring multiple functions and implementations. I've made push, pop, and top functions for this, but I need some others, firstly printStack as the topic says. I'm guessing the other functions will be constructed similar to it. I am hoping there is a simpler way to do printStack other than to make a secondary list and then to print off that. Here's the code for my printstack function, which doesn't work:

CODE
int PrintStack(Node *head, Node **head){
      Node *node = (Node*)malloc(sizeof(Node));     // Allocates memory for Node *node.
      Node *tail = (Node*)malloc(sizeof(Node));     // head for second list called tail.
    while(*head != NULL){
          *head->ptr = node;                        // Head's pointed-at node (second node) is now the first thing of this second list
        node->ptr = *head;                        // Passes *head, the pointer to the head of the list, to the pointer of the current node.
            *head = node;                         // Head's parameters now = node's parameters I guess.
            Node *temp = *head;                   // make a temp node and it equals head now.
            *head = temp->ptr;                    // basically, head = whatever it was pointing to.
             free(temp);                           // free up temp, its done being used.


Here's the rest of my junk. I look forward to a reply.

CODE
/**********
David Wood
**********/


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


typedef struct Node       // new struct, linked list node
    {
        int value;        // holds a value
        struct Node *ptr; // also holds a pointer to next node
    }Node;                // for recursive reference.

Node *head;

/*

//This function is optional. It creates an empty node at the head of an empty list.

void create(Node **head){                         // void returns nothing, name = create, takes in Node head.
    if(*head == NULL){
        Node *node = (Node*)malloc(sizeof(Node)); // Allocates memory for Node *node.
         node->value = NULL;                       // Inserts a value into the current node
        *head = node;                             // Head is the front of the list, so any newly created node is the head.
    }else{
        printf("Head = Null\n");
    }
};

// This function is more trouble than its worth.
*/

//This makes a new node, and inserts on the head of the list. Can be done whether or not there is a list.

void push(int val, Node **head){              // void type returns nothing. name is push. it takes in a user value and a Node.
    Node *node = (Node*)malloc(sizeof(Node)); // Allocates memory for Node *node.
    node->value = val;                        // Passes val, the user's input, to value, node's value slot.
    node->ptr = *head;                        // Passes *head, the pointer to the head of the list, to the pointer of the current node.
    *head = node;                             // Head's parameters now = node's parameters I guess.
}

//Deletes the top node...

int pop(int **head){                          // So its int, dunno why it isnt void
    if(*head == NULL){                        // catches if head is null. if it is, its the beginning of the list, so we can't delete.
         printf("Head = Null\n");             // does something to notify the user they are trying to do something bad.
    }else{                                    // if *head is anything but null.
        Node *temp = *head;                   // make a temp node and it equals head now.
        *head = temp->ptr;                    // basically, head = whatever it was pointing to.
         free(temp);                           // free up temp, its done neing used.
    }
}

//Prints the top node's value.

int top(Node *head){                          // this just takes in a *ptr rather than **ptr, dunno why though.
    if(head == NULL){                         // if head is null, its the beginning of the list.
            printf("Head = Null\n");          // prints this
    }else if(head->value == NULL){            // this is if head's value = null. this shouldnt happen but its possible.
          printf("value = Null\n");           // prints an error
    }else{                                    // otherwise
         printf("%d\n", head->value);         // print head's value.
    }
}
/*
int empty(){
    int x = StackTop;
    StackTop = 0;
    while(StackTop != x){
        array[StackTop] = 0;
        StackTop++;
    }
}
*/


int PrintStack(Node *head, Node **head){
      Node *node = (Node*)malloc(sizeof(Node));     // Allocates memory for Node *node.
      Node *tail = (Node*)malloc(sizeof(Node));     // head for second list called tail.
    while(*head != NULL){
          *head->ptr = node;                        // Head's pointed-at node (second node) is now the first thing of this second list
        node->ptr = *head;                        // Passes *head, the pointer to the head of the list, to the pointer of the current node.
            *head = node;                         // Head's parameters now = node's parameters I guess.
            Node *temp = *head;                   // make a temp node and it equals head now.
            *head = temp->ptr;                    // basically, head = whatever it was pointing to.
             free(temp);                           // free up temp, its done neing used.


    }
}


/*
int FindMax(){
    int x = StackTop;
    StackTop = 0;
    int y = array[StackTop];
    int max = array[StackTop];
    while(StackTop != x){
        int place = array[StackTop];
        if(max<y){
            max = y;
            StackTop++;
        }else{        
            StackTop++;
        }

        y = array[StackTop];
    }
    printf("%d\n", max);
}

int FindMin(){
    int x = StackTop;
    StackTop = 0;
    int y = array[StackTop];
    int min = array[StackTop];
    while(StackTop != x){
        int place = array[StackTop];
        if(min>y){
            min = y;
            StackTop++;
        }else{        
            StackTop++;
        }

        y = array[StackTop];
    }
    printf("%d\n", min);
}

*/

int main(){
    head = NULL;
    int choice = 0;
    while(choice != 9){

        printf("Pick a choice.\n");
        printf("  1) Create new stack\n");
        printf("  2) Push on the stack\n");
        printf("  3) Print the top value\n");
        printf("  4) Print the stack\n");
        printf("  5) Print max value in stack\n");
        printf("  6) Print min value in stack\n");
        printf("  7) Pop on the stack\n");
        printf("  8) Empty the stack\n");
        printf("  9) Quit\n");
                
        scanf("%d", &choice);
        
        if(choice == 1){
            create(&head);
        }
        
        else if(choice == 2){
            int poo = 0;
            scanf("%d", &poo);
            push(poo, &head);
        }
        
        else if(choice == 3){
            top(head);
        }

        else if(choice == 4){
//            PrintStack();
        }

        else if(choice == 5){
//            FindMax();
        }

        else if(choice == 6){
//            FindMin();
        }

        else if(choice == 7){
            pop(&head);
        }

        else if(choice == 8){
//            empty();
        }
    }
    return(1);
};

User is offlineProfile CardPM
+Quote Post

P4wn4g3
RE: Help W/ PrintStack In C
23 Nov, 2007 - 11:03 AM
Post #2

New D.I.C Head
*

Joined: 22 Nov, 2007
Posts: 12


My Contributions
I changed the code for the printStack function. I'm still getting errors. Here's the update:

CODE
int PrintStack(Node **head){
      Node *node = (Node*)malloc(sizeof(Node));     // Allocates memory for Node *node.
      Node *tail = (Node*)malloc(sizeof(Node));     // head for second list called tail.
    while(*head != NULL){
          *head->ptr = node;                        // Head's pointed-at node (second node) is now the first thing of this second list
        node = *head;                             // Passes *head, the pointer to the head of the list, to the pointer of the current node.
        tail->value = head->value;                // Head's parameters now = node's parameters I guess.
        printf(%d, tail->value);
        tail->ptr = head->ptr;                    // make a temp node and it equals head now.
        free(temp);                               // free up temp, its done being used.
    }
}



By the way, those comments are potentially wrong and meaningless...
User is offlineProfile CardPM
+Quote Post

NickDMax
RE: Help W/ PrintStack In C
23 Nov, 2007 - 01:07 PM
Post #3

2B||!2B
Group Icon

Joined: 18 Feb, 2007
Posts: 2,868



Thanked: 53 times
Dream Kudos: 550
My Contributions
What errors?
User is offlineProfile CardPM
+Quote Post

P4wn4g3
RE: Help W/ PrintStack In C
23 Nov, 2007 - 01:22 PM
Post #4

New D.I.C Head
*

Joined: 22 Nov, 2007
Posts: 12


My Contributions
I keep readjusting the code:

CODE
int PrintStack(Node *head){
      Node *bla = (Node*)malloc(sizeof(Node));     // Allocates memory for Node *node.
      Node *tail = (Node*)malloc(sizeof(Node));     // head for second list called tail.
    do while(head->ptr != NULL){
          head = bla;                        // Head's pointed-at node (second node) is now the first thing of this second list
        free(bla);
        tail->value = head->value;               // Head's parameters now = node's parameters I guess.
        printf("%d\n", tail->value);
        tail->ptr = head->ptr;                   // make a temp node and it equals head now.
        free(tail);                               // free up temp, its done being used.
    }
}


I'm getting a syntax error now, at the end bracket (the outside one). This code's goal is to navigate the list and print it...
User is offlineProfile CardPM
+Quote Post

P4wn4g3
RE: Help W/ PrintStack In C
23 Nov, 2007 - 01:53 PM
Post #5

New D.I.C Head
*

Joined: 22 Nov, 2007
Posts: 12


My Contributions
Another change:

CODE

int PrintStack(Node *head){
      Node *bla = (Node*)malloc(sizeof(Node));     // Allocates memory for Node *node.
//      Node *tail = (Node*)malloc(sizeof(Node));     // head for second list called tail.
    bla = head->ptr;
    do while(head->ptr != NULL){
        printf("%d\n", bla->value);                        // Head's pointed-at node (second node) is now the first thing of this second list
        bla = bla->ptr;
    }
    free(bla);                               // free up temp, its done being used.
}


I am still getting a syntax error in front of free(). Dunno whats the problem, hope someone can help, thanks.
User is offlineProfile CardPM
+Quote Post

baavgai
RE: Help W/ PrintStack In C
23 Nov, 2007 - 02:54 PM
Post #6

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,277



Thanked: 135 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua, Cheese

My Contributions
Your pop has a problem, it doesn't return value.

You honestly should be able to find thousands of examples of a linked list, in this case a basic stack, in C. Here's a few hints. The only function that's calling malloc is push; nothing else needs to grab memory. The only method that releases that is pop.

There reason for this exercise to to realise the power and frustration of pointers. Here's my simple version of your code:

CODE

typedef struct Node {       // new struct, linked list node
   int value;        // holds a value
   struct Node *next; // also holds a pointer to next node ( use next, makes reading the rest easier)
} Node;

Node *head = NULL;  // This is a delclaration of the first node in our list

// We are not going to pass head, it is implict to our list
// If we ever move to C++, it will be part of our class
// The theory here is that pointers to pointers ( e.g. **head ) cause brain damage

// I should also be noted the user of these functions is unware that our list uses struct Node or pointers
// They're just doing operations on an integer stack

// push a value onto the stack
void push(int value) {
   Node *newNode = (Node*)malloc(sizeof(Node)); // Allocates memory for Node *node.
   newNode->value = value;
   newNode->next = head;  // make the next node for this new node the current head
   head = newNode;        // the new node is now the head node, our list grows by one
}

void printStack(){
   Node *currentNode = head;      // point to the top of the stack
   while(currentNode != NULL) {   // while the current node is not the end, keep going
      printf("%d\n", currentNode->value);  // show the value
      
      // move on to the next
      // since we change our current pointer to the next, this is why we declare a local current pointer
      // to not mess up the head value
      currentNode = currentNode->next;      
            
    }
}

// Test it.  Don't do the user input thing first, get some examples working, then play with others.
int main(int argc, char** argv) {
   push(5);
   push(4);
   push(3);
   printStack();
}


Hope this helps.

User is offlineProfile CardPM
+Quote Post

P4wn4g3
RE: Help W/ PrintStack In C
23 Nov, 2007 - 03:45 PM
Post #7

New D.I.C Head
*

Joined: 22 Nov, 2007
Posts: 12


My Contributions
Thanks for the help baavgai.
I am still getting errors, though now they are SegFaults at runtime:

CODE
int PrintStack(Node *head){
    Node *bla = head;
    bla = head->next;
    while(bla->next != NULL){ //SegFault occurs here.
        printf("%d\n", bla->value); // print current value
        bla = bla->next; //go to current's next node.
    }
    return(0);
}


Not sure why this is happening. Do you have some ideas?
User is offlineProfile CardPM
+Quote Post

baavgai
RE: Help W/ PrintStack In C
23 Nov, 2007 - 04:38 PM
Post #8

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,277



Thanked: 135 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua, Cheese

My Contributions
This code will actually loose you the first and last node! Here it is with comments:

CODE
int PrintStack(Node *head){
    Node *bla = head; // fine
    bla = head->next; // huh?  You've just skipped the first node.  Also, if the list is empty, this will fail because you have a pointer to null
    while(bla->next != NULL){ //assuming you get this far, you're now checking the node after the current one.  If this is the last node, then next will be null here you dropt the last node.  Also, if bla is null, you fail.  You'll get a seg fault here is your list has one value.
        printf("%d\n", bla->value); // print current value
        bla = bla->next; //go to current's next node.
    }
    return(0); // not sure why you return zero?
}


Given what you have, try this:

CODE
void PrintStack(Node *head){
    Node *bla = head;
    while(bla  != NULL) {
        printf("%d\n", bla->value); // print current value
        bla = bla->next; //go to current's next node.
    }
}


Hope this helps.

User is offlineProfile CardPM
+Quote Post

P4wn4g3
RE: Help W/ PrintStack In C
23 Nov, 2007 - 05:24 PM
Post #9

New D.I.C Head
*

Joined: 22 Nov, 2007
Posts: 12


My Contributions
Yeah, funny thing, right as you posted I found that my node was accessing null illegally. But your snippet helped get me somewhere, except that code only returns a memory address. So thanks. However...

Am I going about printing the list wrong? Since head = the top node, there really is no way to traverse backwards (unless I doubly link this list, which I don't think I'm supposed to do). I haven't ever done this much in terms of linked lists in C, and I've only done some linked lists in Java, though I don't remember the projects.

Anyway, I am now officially stuck. The only other way to maneuver through the list (that I know) is to have some variable, and index it when a new node is created, and somehow assign node numbers.. except that's an array.

blink.gif

So.. can someone steer me in the right direction here?
User is offlineProfile CardPM
+Quote Post

baavgai
RE: Help W/ PrintStack In C
23 Nov, 2007 - 05:39 PM
Post #10

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,277



Thanked: 135 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua, Cheese

My Contributions
Your two methods, beyond the print, are push and pop. This implies a stack. A stack follows the rule of LIFO, last in, first out. Simply, the last element you enter is the top. So, if you push 1,2,3,4, when you pop you're supposed to get 4,3,2,1. This is functioning as intended.

If you want the direction maintained, you must do extra work. When you add a node, you traverse the nodes until you get to the last one, the one with a next of null. You then make the new node the next of the last one. Depending on the implementation, you're making a queue at that point. I takes a little more work and because it's such a pain as the list get large, a second pointer is often maintained for the last node, as well as the first.


User is offlineProfile CardPM
+Quote Post

P4wn4g3
RE: Help W/ PrintStack In C
23 Nov, 2007 - 06:02 PM
Post #11

New D.I.C Head
*

Joined: 22 Nov, 2007
Posts: 12


My Contributions
Actually, making a Queue is part of my project, but a later part. Also, I don't see how the above code is working to print the list... when I push 1 and call PrintStack, it prints 4007136. When I push 2 onto this, I get 4007448. I've confused myself now. How can you reassign things with pointers going only one direction? The head points to Null, not the last node.. or do I have that confused?

Somehow I messed up my pop function as well. I'm going to post the program again...



CODE

/*********
David Wood
*********/


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

//Prototype for linked list

typedef struct Node       // new struct, linked list node
    {
        int value;        // holds a value
        struct Node *next; // also holds a pointer to next node
    }Node;                // for recursive reference.

Node *head;

/*

//This function is optional. It creates an empty node at the head of an empty list.

void create(Node **head){                         // void returns nothing, name = create, takes in Node head.
    if(*head == NULL){
        Node *node = (Node*)malloc(sizeof(Node)); // Allocates memory for Node *node.
         node->value = NULL;                       // Inserts a value into the current node
        *head = node;                             // Head is the front of the list, so any newly created node is the head.
    }else{
        printf("Head = Null\n");
    }
};

// This function is more trouble than its worth.
*/

//This makes a new node, and inserts on the head of the list. Can be done whether or not there is a list.

void push(int val, Node **head){              // void type returns nothing. name is push. it takes in a user value and a Node.
    Node *node = (Node*)malloc(sizeof(Node)); // Allocates memory for Node *node.
    node->value = val;                        // Passes val, the user's input, to value, node's value slot.
    node->next = *head;                        // Passes *head, the pointer to the head of the list, to the pointer of the current node.
    *head = node;                             // Head's parameters now = node's parameters I guess.
}

//Deletes the top node...

void pop(int **head){                          // So its int, dunno why it isnt void
    if(*head == NULL){                        // catches if head is null. if it is, its the beginning of the list, so we can't delete.
         printf("Head = Null\n");             // does something to notify the user they are trying to do something bad.
    }else{                                    // if *head is anything but null.
        Node *temp = *head;                   // make a temp node and it equals head now.
        *head = temp->next;                    // basically, head = whatever it was pointing to.
         free(temp);                           // free up temp, its done being used.
    }
}

//Prints the top node's value.

void top(Node *head){                          // this just takes in a *pointer rather than **pointer, dunno why though.
    if(head == NULL){                         // if head is null, its the beginning of the list.
            printf("Head = Null\n");          // prints this
    }else if(head->value == NULL){            // this is if head's value = null. this shouldnt happen but its possible.
          printf("value = Null\n");           // prints an error
    }else{                                    // otherwise
         printf("%d\n", head->value);         // print head's value.
    }
}

//Prints everything on the stack

void PrintStack(Node *head){
      Node *bla = head;     // Allocates memory for Node *node.
    while(bla != NULL){
        printf("%d\n", bla->value); // Head's pointed-at node (second node) is now the first thing of this second list
        bla = bla->next;
    }
}

int main(){
    head = NULL;
    int choice = 0;
    while(choice != 9){

        printf("Pick a choice.\n");
        printf("  1) Create new stack\n");
        printf("  2) Push on the stack\n");
        printf("  3) Print the top value\n");
        printf("  4) Print the stack\n");
        printf("  5) Print max value in stack\n");
        printf("  6) Print min value in stack\n");
        printf("  7) Pop on the stack\n");
        printf("  8) Empty the stack\n");
        printf("  9) Quit\n");
                
        scanf("%d", &choice);
        
        if(choice == 1){
//            create(&head);
        }
        
        else if(choice == 2){
            int poo = 0;
            scanf("%d", &poo);
            push(poo, &head);
        }
        
        else if(choice == 3){
            top(head);
        }

        else if(choice == 4){
            PrintStack(&head);
        }

        else if(choice == 5){
//            FindMax();
        }

        else if(choice == 6){
//            FindMin();
        }

        else if(choice == 7){
            pop(head);
        }

        else if(choice == 8){
//            empty();
        }
    }
    return(1);
};

User is offlineProfile CardPM
+Quote Post

baavgai
RE: Help W/ PrintStack In C
23 Nov, 2007 - 08:53 PM
Post #12

Dreaming Coder
Group Icon

Joined: 16 Oct, 2007
Posts: 2,277



Thanked: 135 times
Dream Kudos: 475
Expert In: C, C++, Java, C#, ASP.NET, PHP, Perl, Python, Oracle, SQL Server, MySql, HTML, JavaScript, Lua, Cheese

My Contributions
Your push and print code looks fine. However, you may have issues with just having a Node *head; out there as a global. If you're not setting the value, it could start as anything. Also, to avoid confusion, I'd declare the node in main, just to make sure you're passing what you think you're passing.

Your pop is confused. You need to return the top value and shorten the list by a node. I included a pop.

Here's a working example:

CODE

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

//Prototype for linked list

typedef struct Node       // new struct, linked list node
    {
        int value;        // holds a value
        struct Node *next; // also holds a pointer to next node
    }Node;                // for recursive reference.



void push(int val, Node **head){              // void type returns nothing. name is push. it takes in a user value and a Node.
    Node *node = (Node*)malloc(sizeof(Node)); // Allocates memory for Node *node.
    node->value = val;                        // Passes val, the user's input, to value, node's value slot.
    node->next = *head;                        // Passes *head, the pointer to the head of the list, to the pointer of the current node.
    *head = node;                             // Head's parameters now = node's parameters I guess.
}

// pop removes, and returns, the top value off the stack
int pop(Node **head){                         // So its int, dunno why it isnt void
   int returnValue = -1;                     // value defaults to -1 if empty; something must be returned.
   if(*head == NULL) {                       // catches if head is null. if it is, its the beginning of the list, so we can't delete.
         printf("Head = Null\n");             // does something to notify the user they are trying to do something bad.
    } else {                                  // if *head is anything but null.
        Node *temp = *head;                   // make a temp node and it equals head now.
    returnValue = temp->value;            // set return value
        *head = temp->next;                    // basically, head = whatever it was pointing to.
    free(temp);                           // free up temp, its done being used.
    }
   return returnValue; // no matter what, user gets return value
}


void PrintStack(Node *head) {
   Node *bla = head;     // Allocates memory for Node *node.
    while(bla != NULL){
        printf("%d\n", bla->value); // Head's pointed-at node (second node) is now the first thing of this second list
        bla = bla->next;
    }
}

int m