Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Absurd lab assignment

  1. Jan 27, 2006 #1
    We just covered lists and queue's on thursday. Our lab is the following question. I know my C quite well but i just don't understand whats required of us. If i could get a rough idea before the next lab:

    lab 6:

    Objectives
    Understand the inner workings of stacks; practice working with structures and pointers.
    Instructions

    1. Copy and unpack Stack.tgz. Change directory into Stacks.
    2. Define elem to be structures consisting of a string that holds a short description of the type of data pointed to by the second field, a void *.
    3. Modify the stacks to store elems using a type definition in stack.h. Modify all the files in the stack distribution to reflect this generalisation. Now your stacks can store (pointers to) arbitrary data. The print (and rprint) stack functions should call a yet to be written new function printelem for printing individual elements.
    4. Write a definition for void printelem(elem e) into printelem.c. Your printelem must cope at least with data of type int, float, and char. Adapt stack.h and the Makefile.
    5. Modify testStack.c such that all the new functionality can be properly tested.
    6. Copy the solution to question 4 of last weeks tute into fcalc.c. Modify it to work with floating point numbers in input and output. Use your new stacks for this. Adapt the Makefile once again so that by default it builds two targets: the new calculator fcalc and the stack tester testStack.
    7. When all this works, submit your lab work:



    Makefile:
    CFLAGS = -Wall -ansi -pedantic -ggdb

    CFILES := $(wildcard *.c)
    HFILES := $(wildcard *.h)
    OFILES := $(patsubst %.c,%.o,$(CFILES))

    .PHONY : all clean

    testStack: $(OFILES)
    $(CC) $(CFLAGS) -o testStack $(OFILES) -lm

    $(OFILES): $(HFILES) Makefile

    all: testStack

    clean:
    rm -f $(OFILES) testStack


    stack.h
    wagner % emacs popStack.c
    wagner % emacs stack.h
    File Edit Options Buffers Tools C Cscope Help
    /* stacks with integer content */
    struct stack {
    int info;
    struct stack *belowPtr;
    struct elem *elemPtr;
    };

    /*edited data*/
    struct elem{
    char *str;
    void *ptr;
    };


    typedef struct stack *Stack;

    typedef struct elem *Elem;


    /* descriptive names for 0 and 1 as return values */
    typedef enum {Failure, Success} RetVal;

    /* descriptive names for 0 and 1 as Boolean values */
    typedef enum {False, True} Boolean;

    /* stack operations galore */
    RetVal push (Stack *, int);
    void pop (Stack *);
    int top (Stack);
    Boolean isempty (Stack);
    void printStack (Stack);
    void printStack_r (Stack);


    stack.h

    File Edit Options Buffers Tools C Cscope Help
    #include <stdio.h>
    #include <stdlib.h>
    #include "stack.h"

    /* pop the top element from a stack */
    void pop (Stack *sp)
    {
    Stack tempPtr = *sp;
    //Elem tempElem = e;


    if (isempty (*sp))
    {
    fprintf (stderr, "Error: tried to pop an empty stack.\n");
    exit (EXIT_FAILURE);
    }
    if((*sp)->elemPtr != NULL)
    freed((*sp)->elemPtr)

    *sp = tempPtr->belowPtr;
    free (tempPtr);


    }


    topStack.c
    wagner % emacs testStack.c
    wagner % emacs topstack.c
    wagner % emacs topStack.c
    File Edit Options Buffers Tools C Cscope Help
    #include <stdio.h>
    #include <stdlib.h>
    #include "stack.h"

    Boolean isempty (Stack s)
    {
    return s == NULL;
    }



    /* show the top element of a stack */
    int top (Stack s)
    {
    if (isempty (s))
    {
    printf ("Error: tried to access top element of an empty stack.\n");
    exit (EXIT_FAILURE);
    }
    else
    return s->info; /* look into the label of *s */

    }

    pushStack.c
    #include <stdlib.h>
    #include "stack.h"

    /* push an integer on top of a stack */
    RetVal push (Stack *sp, int data,char *str, void *data2)
    {
    Stack newPtr;
    Elem elemPtr;

    /* Step 1: create a fresh stack element. */
    if ((newPtr = malloc (sizeof (struct stack))) == NULL)
    return Failure;
    if ((elemPtr = malloc (sizeof (struct elem))) == NULL)
    return Failure;

    /* Copy data to the fresh stack element. */
    newPtr->info = data;
    elemPtr->str = str;
    /* The new stack has the new element as top followed by the old stack. */
    newPtr->belowPtr = *sp;
    *sp = newPtr;

    elemPtr->ptr = data2;


    return Success;
    }

    printStack.c

    #include <stdio.h>
    #include "stack.h"

    /* print a stack - iterative version */
    void printStack (Stack s)
    {
    for (; !isempty (s); s = s->belowPtr)
    printf(" | %5d |\n"
    " ---------\n", s->info);

    }

    /* print a stack - recursive version */
    void printStack_r (Stack s)
    {
    if (!isempty (s))
    {
    printf(" | %5d |\n"
    " ---------\n", s->info);
    printStack_r (s->belowPtr);
    }
    }



    testStack.c
    #include <stdio.h>
    #include <string.h>
    #include "stack.h"

    #define NCOMMANDS 8
    int
    main ()
    {
    void instructions (void);
    size_t findcommand (const char *command, const char *dict[],
    size_t dictlen, size_t signchars);
    char tmp;
    const char *dict[NCOMMANDS] =
    {"isempty", "top", "push", "pop", "print", "rprint", "?", "Q"};
    enum {ISEMPTY, TOP, PUSH, POP, PRINT, RPRINT, INSTRUCTIONS, QUIT};
    Stack s = NULL;

    int i;
    char command[1024];
    size_t c;
    void *datatmp;

    Boolean go = True;

    instructions ();

    while (go && scanf ("%s", command) == 1) {
    c = findcommand (command, dict, NCOMMANDS, 2);
    switch (c) {
    case ISEMPTY:
    printf ("The stack is %sempty.\n", isempty (s) ? "" : "not ");
    break;
    case TOP:
    printf ("On top of the stack is %d.\n", top (s));
    break;
    case PUSH:
    printf("\nWhat kind of data will you input \n");

    switch(scanf("%c",&tmp))
    case 'c':
    printf("enter your data\n");
    scanf("%c",datatmp);
    str = "char";
    break;
    case 'i':
    printf("enter your data\n");
    scanf("%d",datatmp);str = "int";
    break;
    case 'f':
    printf("enter your data\n");
    scanf("%f",datatmp);str = "float";
    break;
    default:
    printf("Error encountered - wrong entry");
    break;


    //scanf ("%d", &i);

    if (push (&s, i,str,datatmp. ) == Failure)
    printf ("Error in malloc: push failed!\n");
    break;
    case POP:
    pop (&s);
    printf ("*** pop ***\n");
    break;
    case PRINT:
    printf ("Printing the stack iteratively:\n");
    printStack (s);
    break;
    case RPRINT:
    printf ("Printing the stack recursively:\n");
    printStack (s);
    break;
    case INSTRUCTIONS:
    instructions ();
    break;
    case QUIT:
    go = False;
    break;
    default:
    printf ("Pardon?\n");
    }
    }
    printf ("\nGood bye.\n\n");
    return 0;
    }

    void instructions (void)
    {
    printf ("Play with a stack of integers by issuing commands.\n"
    "(The first two letter of a command name suffice.)\n"
    "Command Effect\n"
    " push n push n onto the stack\n"
    " pop pop one element from the stack\n"
    " top show the top element of the stack\n"
    " isempty show whether the stack is empty\n"
    " print print the stack iteratively\n"
    " rprint print the stack recursively\n"
    " ? read these instructions again\n"
    " Q stop\n");
    }

    /**
    * findcommand - general purpose command detection
    * @command the command to decypher
    * @dict recognised commands
    * @dictlen length of dict
    * @signchar number of significant characters in commands
    * Return values: the subscript of command in dict,
    * or dictlen if none matches
    */
    size_t findcommand (const char *command, const char *dict[],
    size_t dictlen, size_t signchars)
    {
    size_t r;
    for (r = 0; r < dictlen; r++)
    if (strncmp (dict[r], command, signchars) == 0)
    break;
    return r;
    }




    fcalc.c

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

    /* this is our standard stack implementation */
    #include "stack.h"

    int isop (char c);

    int main()
    {
    Stack stack = NULL;
    float c;
    float number = 0, op1, op2;

    while((c = getchar()) != EOF) {
    if (c == '\n') { /* we're done - print the result which is at
    the top of the stack */
    printf("Expression evaluates to %d\n", top(stack));
    exit(0); /* we could reset things and keep evaluating
    expressions instead of exiting */
    } else if(isdigit(c)) { /* we need to get and store the integer */
    number = c -'0';
    while(isdigit(c = getchar()))
    number = (number * 10) + c - '0';
    ungetc (c, stdin); /* push pack the non-digit just read */
    push(&stack, number);
    } else if (isop (c)) { /* it must be an operator - we assume correct input */
    /* get the first two numbers from the stack and perform
    necessary operation storing it back on stack */
    op1 = top(stack);
    pop(&stack);
    op2 = top(stack);
    pop(&stack);
    switch(c) {
    case '+':
    push(&stack, op1 + op2);
    break;
    case '*':
    push(&stack, op1 * op2);
    break;
    case '-':
    push(&stack, op2 - op1);
    }
    }
    }

    return EXIT_SUCCESS;
    }

    int isop (char c)
    {
    return c == '+' || c == '*' || c == '-';
    }


    -bash: printelem.c: command not found
    wagner % emacs printelem.c
    File Edit Options Buffers Tools C Cscope Help
    #include <stdio.h>
    #include "stack.h"

    void printelem(elem e)
    {
    void tempInput;

    for (; e!= e->NULL; e = e->elemPtr)
    printf(" | %5d |\n"
    " ---------\n", s->info);


    }



    -----------------------------------------------------------------------
    :bugeye: good god what are we supposed to do.

    The code has already been modified by me.
    I know we need to have a struct inside a struct. The second struct is called elem which contains a string and a void pointr (void*ptr) to an element. We don't have much specifics here how do we know whats expected of us :cry: .

    Oh well.

    ALso for the printelem function we need to be able to print whatever is being pointed to by the void printer - whether its a int, char, float or string.

    Note this is supposed to be finished in 2hrs! reading time inclusive

    help!!
     
  2. jcsd
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Can you help with the solution or looking for help too?
Draft saved Draft deleted



Similar Discussions: Absurd lab assignment
  1. C++ assignment (Replies: 7)

Loading...