Skip to content
Snippets Groups Projects
Commit 67140dbe authored by florian.burgener's avatar florian.burgener
Browse files

Initial commit

parents
Branches
No related tags found
No related merge requests found
Makefile 0 → 100644
CC = gcc
CCFLAGS = -g -Wall -Wextra -pedantic -fsanitize=address -fsanitize=leak
hashmap.o: hashmap.c hashmap.h
$(CC) $(CCFLAGS) -c $< -o $@
main.o: main.c
$(CC) $(CCFLAGS) -c $< -o $@
contacts_database: main.o hashmap.o
$(CC) $(CCFLAGS) -o contacts_database main.o hashmap.o
clean:
rm -f *.o contacts_database
hashmap.c 0 → 100644
#include "hashmap.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct hm_t {
struct entry_t **entries;
int length;
};
struct entry_t {
char *key;
char *value;
struct entry_t *next;
};
entry_t *hm_get_entry(const hm_t *const hm, const char *const key);
entry_t *hm_get_entry_before(const hm_t *const hm, entry_t *entry);
hm_t *hm_create(unsigned int length) {
hm_t *hm = (hm_t *)malloc(sizeof(hm_t));
hm->length = length;
hm->entries = (entry_t **)malloc(sizeof(entry_t *) * hm->length);
for (int i = 0; i < hm->length; i += 1) {
hm->entries[i] = NULL;
}
return hm;
}
void hm_destroy(hm_t **hm) {
for (int i = 0; i < (*hm)->length; i += 1) {
entry_t *iterator = (*hm)->entries[i];
while (iterator != NULL) {
entry_t *tmp = iterator;
iterator = iterator->next;
free(tmp->key);
free(tmp->value);
free(tmp);
}
}
free((*hm)->entries);
free(*hm);
*hm = NULL;
}
int hash(hm_t *hm, const char *const key) {
int hash_value = 0;
for (int i = 0; i < (int)strlen(key); i += 1) {
hash_value = 43 * hash_value + key[i];
}
return hash_value % hm->length;
}
hm_t *hm_set(hm_t *hm, const char *const key, const char *const value) {
entry_t *entry = hm_get_entry(hm, key);
if (entry != NULL) {
entry->value = (char *)value;
return hm;
}
int index = hash(hm, key);
entry_t *new_entry = (entry_t *)malloc(sizeof(entry_t));
new_entry->key = (char *)key;
new_entry->value = (char *)value;
new_entry->next = NULL;
if (hm->entries[index] == NULL) {
hm->entries[index] = new_entry;
} else {
entry_t *iterator = hm->entries[index];
while (iterator->next != NULL) {
iterator = iterator->next;
}
iterator->next = new_entry;
}
return hm;
}
entry_t *hm_get_entry(const hm_t *const hm, const char *const key) {
int index = hash((hm_t *)hm, key);
entry_t *iterator = hm->entries[index];
while (iterator != NULL && strcmp(iterator->key, key) != 0) {
iterator = iterator->next;
}
return iterator;
}
entry_t *hm_get_entry_before(const hm_t *const hm, entry_t *entry) {
int index = hash((hm_t *)hm, entry->key);
entry_t *iterator = hm->entries[index];
if (iterator == entry) {
return NULL;
}
while (iterator->next != entry) {
iterator = iterator->next;
}
return iterator;
}
char *hm_get(const hm_t *const hm, const char *const key) {
entry_t *entry = hm_get_entry(hm, key);
if (entry == NULL) {
return NULL;
}
return entry->value;
}
char *hm_rm(hm_t *hm, const char *const key) {
entry_t *entry = hm_get_entry(hm, key);
if (entry == NULL) {
return NULL;
}
entry_t *entry_before = hm_get_entry_before(hm, entry);
if (entry_before == NULL) {
int index = hash(hm, key);
hm->entries[index] = hm->entries[index]->next;
} else {
entry_before->next = entry_before->next->next;
}
char *value = entry->value;
free(entry);
return value;
}
char *hm_to_str(const hm_t *const hm) {
char *str = (char *)malloc(sizeof(char) * 100000);
str[0] = '\0';
for (int i = 0; i < hm->length; i += 1) {
char header[100];
sprintf(header, "%d: ", i);
strcat(str, header);
entry_t *iterator = hm->entries[i];
while (iterator != NULL) {
strcat(str, "(");
strcat(str, iterator->key);
strcat(str, ": ");
strcat(str, iterator->value);
strcat(str, ")");
iterator = iterator->next;
if (iterator != NULL) {
strcat(str, ", ");
}
}
strcat(str, "\n");
}
return str;
}
void hm_print(const hm_t *const hm) {
char *str = hm_to_str(hm);
printf("%s", str);
free(str);
}
#ifndef HASHMAP_H
#define HASHMAP_H
typedef struct hm_t hm_t;
typedef struct entry_t entry_t;
hm_t *hm_create(unsigned int length);
void hm_destroy(hm_t **hm);
hm_t *hm_set(hm_t *hm, const char *const key, const char *const value);
char *hm_get(const hm_t *const hm, const char *const key);
char *hm_rm(hm_t *hm, const char *const key);
char *hm_to_str(const hm_t *const hm);
void hm_print(const hm_t *const hm);
#endif
main.c 0 → 100644
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "hashmap.h"
void clear_buffer() {
int c;
while ((c = getchar()) != '\n' && c != EOF) {
}
}
int main() {
struct hm_t *hm = hm_create(2);
while (true) {
printf("1=exit, 2=add, 3=delete, 4=search: ");
int action;
scanf("%d", &action);
clear_buffer();
if (action < 1 || action > 4) {
printf("Invalid action!\n");
continue;
}
char key[100];
char value[100];
if (action == 1) {
break;
} else if (action == 2) {
printf("Phone Number: ");
scanf("%s", key);
clear_buffer();
printf("Name: ");
scanf("%s", value);
clear_buffer();
char *a = strdup(key);
char *b = strdup(value);
hm_set(hm, a, b);
} else if (action == 3) {
printf("Phone Number: ");
scanf("%s", key);
clear_buffer();
hm_rm(hm, key);
} else if (action == 4) {
printf("Phone Number: ");
scanf("%s", key);
clear_buffer();
char *v = hm_get(hm, key);
printf("Name = %s\n", v);
}
}
hm_destroy(&hm);
return EXIT_SUCCESS;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment