Commit a3440127 authored by Dominik Widhalm's avatar Dominik Widhalm
Browse files

Added example solutions for task 6.09

parent e2271526
/******************************************************************************
* C PROGRAMMING *
* BASIC EXERCISES - EXAMPLE SOLUTIONS *
* *
* Task_6.09: Stack *
* Author: Dominik Widhalm *
* Email: dominik.widhalm@technikum-wien.at *
* Date: 2017-08-22 *
* *
******************************************************************************/
/***** INCLUDES ***************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/***** MACROS *****************************************************************/
// Maximum length of strings
#define STRING_MAX 40
// Maximum stack size
#define STACK_MAX 10
/***** TYPEDEFS ***************************************************************/
/* Enumeration type for push & pop return value */
typedef enum {OK, EMPTY, FULL} retval_t;
/* Struct type for the single linked list */
typedef struct cmd {
// Command (string)
char command[STRING_MAX];
// Pointer to next element
struct cmd *next;
} cmd_t;
/***** FUNCTION PROTOTYPES ****************************************************/
retval_t stack_push (cmd_t **head, char *command);
retval_t stack_pop (cmd_t **head, char *command);
void stack_print (cmd_t *head);
/***** LOCAL FUNCTIONS ********************************************************/
/******************************************************************************
* stack_push *
* @brief Function to push a command on the stack. *
* *
* This function first checks if the stack is full. If not, it pushes *
* the given command on the stack (adding it as first element). *
* *
* @param head Pointer to pointer to the first stack element *
* @param command Pointer to the desired command *
* @retval OK Pushing successfull *
* @retval FULL Pushing failed -- stack is full *
******************************************************************************/
retval_t stack_push (cmd_t **head, char *command) {
/* Temporary pointer to the current stack element */
cmd_t *curr = *head;
/* Temporary variable for the stack size */
int size = 0;
/* Retrieve the current stack size */
while (curr != NULL) {
/* Increase stack size counter */
size++;
/* Go to next element */
curr = curr->next;
}
/* Check if stack maximum size is already reached */
if (size >= STACK_MAX) {
/* Stack is full, cannot push */
return FULL;
}
/* Allocate memory for the new command */
curr = (cmd_t*)malloc(sizeof(cmd_t));
/* Copy the command string */
strcpy(curr->command,command);
/* Set the pointers accordingly */
curr->next = *head;
*head = curr;
/* Pushing successful */
return OK;
}
/******************************************************************************
* stack_pop *
* @brief Function to pop a command from the stack. *
* *
* This function first checks if the stack is empty. If not, it pops *
* the next command from the stack. *
* *
* @param head Pointer to pointer to the first stack element *
* @param command Pointer to the readback command *
* @retval OK Popping successfull *
* @retval FULL Popping failed -- stack is empty *
******************************************************************************/
retval_t stack_pop (cmd_t **head, char *command) {
/* Temporary pointer to the current stack element */
cmd_t *curr = *head;
/* Check if stack is empty */
if (curr == NULL) {
/* Stack is empty, cannot pop */
return EMPTY;
}
/* Get the command from the current top element */
strcpy(command,(*head)->command);
/* Remove first element from the stack */
*head = curr->next;
free(curr);
/* Popping successful */
return OK;
}
/******************************************************************************
* stack_print *
* @brief Function to print the current stack. *
* *
* This function prints the current content of the stack (recursively). *
* *
* @param head Pointer to the first stack element *
******************************************************************************/
void stack_print (cmd_t *head) {
/* Print list recursively */
if (head != NULL) {
/* Print current element */
printf("-> \"%s\"\n",head->command);
/* Call function with next element */
stack_print(head->next);
}
/* A void function has nothing to return */
return;
}
/***** MAIN ROUTINE ***********************************************************/
int main (void) {
/*** Local Variables ***/
cmd_t *head = NULL;
cmd_t *next;
char select = 'x';
char command[STRING_MAX];
/* Do as long as the users wants to do an action */
do {
/* Ask the user to select an action */
printf("\nWant do you want to do?\n");
printf("(i) insert a command (push)\n");
printf("(r) retrieve next command (pop)\n");
printf("(p) print current stack\n");
printf("(x) exit\n");
printf("Input: ");
/* Read in the user's input */
scanf(" %c",&select);
/* Do required action */
switch (select) {
case 'i':
/** Insert a command **/
/* Ask the user to input the command */
printf("Please enter the desired command: ");
/* Read in the user's input */
scanf("%s",command);
/* (Try to) push the command on the stack */
if (stack_push(&head,command) == FULL) {
/* Command cannot be pushed, stack is full */
printf("\nFAILED -- Stack is already full!\n\n");
} else {
/* Command has been successfully pushed */
printf("\nPUSHED\n\n");
}
/** Finished inserting **/
break;
case 'r':
/** Retrieve next command **/
/* (Try to) pop the next command from the stack */
if (stack_pop(&head,command) == EMPTY) {
/* Cannot pop, stack is empty */
printf("\nFAILED -- Stack is empty!\n\n");
} else {
/* Command has been successfully pushed */
printf("\nPOPPED: \"%s\"\n\n",command);
}
/** Finished retrieving **/
break;
case 'p':
/** Print the current stack */
if (head == NULL) {
printf("\n... Stack is empty ...\n\n");
} else {
printf("\n... Current stack ...\n");
stack_print(head);
printf("\n");
}
/** Finished printing **/
break;
}
} while (select != 'x');
/* Release the allocated memory (use pointer "next" as helper) */
while (head != NULL) {
/* Save pointer to current element */
next = head;
/* Set head to the next element */
head = next->next;
/* Free memory of current element */
free(next);
}
/* Notify the user about the termination of the program */
printf("\nThe program will now be terminated...\n");
return 0; /* Return with Success (0) */
}
/******************************************************************************/
# Get the current path(s) (relevant directory on last position)
TASKPATH := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
CHPATH := $(dir $(TASKPATH:%/=%))
# Variables for text substitution
empty:=
slash:= /
space:= $(empty) $(empty)
task:= task_
ch:= ch_
# Get TASK number
TASK := $(subst $(slash),$(space),$(TASKPATH))
TASK := $(lastword $(TASK))
TASK := $(subst $(task),$(empty),$(TASK))
# Get CH number
CH := $(subst $(slash),$(space),$(CHPATH))
CH := $(lastword $(CH))
CH := $(subst $(ch),$(empty),$(CH))
# Specify SRD directory
SRCDIR = .
# Call superior makefile
include ../../makefile
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment