-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 1bafc5b
Showing
8 changed files
with
324 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/obj | ||
/bin | ||
/.vscode | ||
|
||
*.o | ||
*.d | ||
*.exe |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
### Static-Queue in C | ||
|
||
This is a static queue implementation in C. It is able to store any kind of data since it is written with a `void*` array to store the data. Note that if you pass pointer as type for the queue, you will need to handle the dealocation of the element each time you dequeue one. | ||
|
||
## Folder-organisation | ||
|
||
In the inc folder you will find the header for each files In the src folder you will find the implementation of all the function. | ||
Here the `main` and the `ui` files are just mean as an utilization example. | ||
|
||
## How to use it | ||
|
||
First you will need to build the project, the makefile is provided with the program, so you just need to enter the following command at the racine of the workspace folder: mingw32-make. Ok so now, you have build the project, (the makefile is setup to compile the program for debug mode) you can now run the program by running the following once again at the racine of the workspace folder : .\bin\main. | ||
|
||
In the program, you will be able to use multiple commands. They will be presented to you by a menu when the program is running. | ||
|
||
## Warning | ||
|
||
Please do not create the bin and obj folder. They will be created by the makefile. Plus do not touch to the created files inside those two folders. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#ifndef STATIC_QUEUE_H | ||
#define STATIC_QUEUE_H | ||
|
||
#include <stdbool.h> | ||
|
||
typedef struct static_queue { | ||
void* arr; | ||
size_t elem_size; | ||
int max_size; | ||
int front_index; | ||
int rear_index; | ||
} static_queue; | ||
|
||
static_queue* staticQueue_init(size_t elem_size, int max_size); | ||
unsigned staticQueue_size(static_queue* queue); | ||
bool staticQueue_isEmpty(static_queue* queue); | ||
void staticQueue_empty(static_queue* queue); | ||
void* staticQueue_front(static_queue* queue); | ||
void* staticQueue_end(static_queue* queue); | ||
bool staticQueue_push(static_queue* queue, void* elem); | ||
void* staticQueue_pop(static_queue* queue); | ||
bool resize(static_queue* queue, int size); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* @file ui.h | ||
* @author Thomas DUCLOS | ||
* @brief this is the header file for the user interface. | ||
* @version 1.2 | ||
* @date 2022-10-05 | ||
* | ||
* @copyright Copyright (c) 2022 | ||
* | ||
*/ | ||
#ifndef UI_H | ||
#define UI_H | ||
|
||
#include <stdbool.h> | ||
|
||
void Menu(); | ||
int Choice(); | ||
bool isWrongMenuChoice(int choice); | ||
|
||
bool parseInt(char *str, int* val); | ||
bool getInt(int* val); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Directory Settings | ||
BUILD_DIR := bin | ||
SRC_DIR := src | ||
OBJ_DIR := obj | ||
INC_DIR := inc | ||
DEP_DIR := obj | ||
|
||
#EXTENSION | ||
SRC_EXT := c | ||
INC_EXT := h | ||
OBJ_EXT := o | ||
DEP_EXT := d | ||
|
||
CXX := gcc #compilator flag | ||
# -Wall : turn on most of the information | ||
# -g : turn on debug info | ||
CXXFLAGS := -Wall -g | ||
LDFLAGS := -I$(INC_DIR) | ||
|
||
# Files loading | ||
FILES := $(wildcard $(SRC_DIR)/*.$(SRC_EXT)) # load all the *.c files | ||
OBJECTS := $(FILES:$(SRC_DIR)/%.$(SRC_EXT)=$(OBJ_DIR)/%.$(OBJ_EXT)) # convert all the *.c into .o object inside the ./obj/ directory | ||
INCLUDES := $(wildcard $(INC_DIR)/*.$(INC_EXT)) # load all the header files | ||
DEPS := $(FILES:%.$(SRC_EXT)=$(OBJ_DIR)/%.$(OBJ_EXT)) # convert all the *.c into .d dependancies inside the ./obj/ directory | ||
EXEC := main # name of the executable generated | ||
|
||
# main execution | ||
all: $(BUILD_DIR)/$(EXEC) | ||
|
||
# build the executable by linking the object and creating the bin directory if not already created | ||
$(BUILD_DIR)/$(EXEC): $(OBJECTS) | $(BUILD_DIR) | ||
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) | ||
|
||
# build all the object and dependancies files from the *.c files | ||
$(OBJ_DIR)/%.$(OBJ_EXT): $(SRC_DIR)/%.$(SRC_EXT) $(INCLUDES) | $(OBJ_DIR) | ||
$(CXX) -c $(CXXFLAGS) $(LDFLAGS) $< -o $@ | ||
$(CXX) -MM $(CXXFLAGS) $(LDFLAGS) $< > $(DEP_DIR)/$*.$(DEP_EXT) | ||
|
||
# create the directory build | ||
$(BUILD_DIR): | ||
mkdir bin | ||
|
||
# create the object build | ||
$(OBJ_DIR): | ||
mkdir obj | ||
|
||
# clean all the project | ||
.PHONY: clean mrproper | ||
|
||
clean: | ||
rm *.$(OBJ_EXT) | ||
|
||
mrproper: clean | ||
rm $(EXEC) | ||
|
||
# pull in dependency info for *existing* .o files | ||
-include $(OBJECTS:.$(OBJ_EXT)=.$(DEP_EXT)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#include <stdlib.h> | ||
#include <stdio.h> | ||
#include <stdbool.h> | ||
#include "static_queue.h" | ||
#include "ui.h" | ||
|
||
int main(int argc, char const *argv[]) | ||
{ | ||
static_queue* queue = staticQueue_init(sizeof(int), 10); | ||
int elem = 0, choice = 0; | ||
|
||
if(queue == NULL) return EXIT_FAILURE; | ||
|
||
do { | ||
Menu(); | ||
choice = Choice(); | ||
if(isWrongMenuChoice(choice)) continue; | ||
switch (choice) | ||
{ | ||
case 1: | ||
printf("Write the value of the element to be insert : "); | ||
while(!getInt(&elem)) { | ||
printf("Failed to parse an integer from the input.\n"); | ||
} | ||
if(!staticQueue_push(queue, &elem)) { | ||
printf("Failed to add element to queue.\n"); | ||
continue; | ||
} | ||
break; | ||
case 2: | ||
printf("Front element is : %d and is at index : %d.\n", *(int*)staticQueue_front(queue), queue->front_index); | ||
break; | ||
case 3: | ||
printf("Rear element is : %d and is at index : %d.\n", *(int*)staticQueue_end(queue), queue->rear_index - 1); | ||
break; | ||
case 4: { | ||
int* dequeu_elem = NULL; | ||
dequeu_elem = (int*)staticQueue_pop(queue); | ||
if(dequeu_elem == NULL) { | ||
printf("Queue is empty !\n"); | ||
continue; | ||
} | ||
printf("Dequeue an element which has the value %d\n", *dequeu_elem); | ||
break; | ||
} | ||
case 5: | ||
staticQueue_empty(queue); | ||
break; | ||
case 6: | ||
printf("Leaving...\n"); | ||
break; | ||
default: | ||
printf("No action corresponding to the choice.\n"); | ||
break; | ||
} | ||
} while(choice != 6); | ||
|
||
free(queue->arr); | ||
free(queue); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include "static_queue.h" | ||
|
||
static_queue* create_pStaticQueue() { | ||
static_queue* temp = NULL; | ||
temp = malloc(sizeof(static_queue)); | ||
return temp; | ||
} | ||
|
||
static_queue* staticQueue_init(size_t elm_size, int max_size) { | ||
static_queue* temp = create_pStaticQueue(); | ||
if(temp == NULL) return NULL; | ||
|
||
temp->arr = calloc(max_size, elm_size); | ||
if(temp->arr == NULL) return NULL; | ||
temp->elem_size = elm_size; | ||
temp->front_index = 0; | ||
temp->rear_index = 0; | ||
temp->max_size = max_size; | ||
return temp; | ||
} | ||
|
||
unsigned staticQueue_size(static_queue* queue) { | ||
return queue->rear_index - queue->front_index; | ||
} | ||
|
||
bool staticQueue_isEmpty(static_queue* queue) { | ||
return staticQueue_size(queue) == 0; | ||
} | ||
|
||
void staticQueue_empty(static_queue* queue) { | ||
queue->front_index = 0; | ||
queue->rear_index = 0; | ||
} | ||
|
||
void* staticQueue_front(static_queue* queue) { | ||
return (char*)(queue->arr) + (queue->front_index * queue->elem_size); | ||
} | ||
|
||
void* staticQueue_end(static_queue* queue) { | ||
return (char*)(queue->arr) + ((queue->rear_index - 1) * queue->elem_size); | ||
} | ||
|
||
bool staticQueue_push(static_queue* queue, void* elem) { | ||
int insert_index = queue->rear_index >= queue->max_size ? 0 : queue->rear_index; | ||
if(insert_index == queue->front_index && !staticQueue_isEmpty(queue)) return false; | ||
memcpy(((char*) queue->arr) + (insert_index) * queue->elem_size, elem, queue->elem_size); | ||
queue->rear_index = insert_index + 1; | ||
return true; | ||
} | ||
|
||
void* staticQueue_pop(static_queue* queue) { | ||
void *pop_elem = NULL; | ||
if(staticQueue_isEmpty(queue)) return NULL; | ||
pop_elem = (char*)queue->arr + queue->front_index * queue->elem_size; | ||
queue->front_index = queue->front_index + 1 > queue->max_size - 1 ? 0 : queue->front_index + 1; | ||
return pop_elem; | ||
} | ||
|
||
bool resize(static_queue* queue, int size) { | ||
return false; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/** | ||
* @file ui.c | ||
* @author Thomas DUCLOS | ||
* @brief Source file for the ui header. In this source file you can find all the function relative to the interaction with the user. | ||
* @version 1.2 | ||
* @date 2022-10-04 | ||
* @copyright Copyright (c) 2022 | ||
*/ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <limits.h> | ||
#include <errno.h> | ||
#include <time.h> | ||
#include "ui.h" | ||
|
||
/// @brief Retrieve an integer from a string by type checking the content of the string. | ||
/// @param str the string containing the data to be parsed. | ||
/// @param val the integer value that has been extract | ||
/// @return true if success | ||
bool parseInt(char *str, int* val){ | ||
errno = 0; | ||
char *temp = NULL; | ||
long res = strtol(str, &temp, 10); | ||
|
||
///Test if there is an error in the input and handle it | ||
///We are checking for integer range because we want to retrieve an int | ||
if (temp == str || *temp != '\n' || | ||
((res > INT_MAX || res < INT_MAX ) && errno == ERANGE)) | ||
return false; | ||
|
||
*val = (int) res; ///Cast from long to integer | ||
return true; | ||
} | ||
|
||
/// @brief Get a integer number with safe input methods | ||
/// @param val the integer value to be retrieve | ||
/// @return true if success | ||
bool getInt(int* val) { | ||
char buffer[500]; | ||
fgets(buffer, 500, stdin); ///Safe way to get a string | ||
return parseInt(buffer, val); | ||
} | ||
|
||
/// @brief The user's menu. This menu is only intend for this program. | ||
void Menu() { | ||
printf("Menu :\n"); | ||
printf("1. Insert in queue.\n"); | ||
printf("2. Print front.\n"); | ||
printf("3. Print end.\n"); | ||
printf("4. Dequeue.\n"); | ||
printf("5. Empty the queue.\n"); | ||
printf("6. Leave\n"); | ||
} | ||
|
||
/// @brief Function to retrieve the choice made by user inside the menu | ||
/// @return -1 on error | ||
int Choice() { | ||
int choice = 0; | ||
|
||
printf("Your choice : "); | ||
|
||
if(getInt(&choice)) | ||
return choice; | ||
return -1; ///Error to handle. | ||
} | ||
|
||
|
||
bool isWrongMenuChoice(int choice) { | ||
return choice == -1 || (choice > 7 || choice < 0); | ||
} | ||
|