diff --git a/a.c b/a.c deleted file mode 100644 index 29f74807e224eef5a79c94cd316e9e4eaa06002a..0000000000000000000000000000000000000000 --- a/a.c +++ /dev/null @@ -1,123 +0,0 @@ -// CAUTION : validation des entrées -#include <stdio.h> -#include <stdlib.h> - -#include "Directory.h" -#include "DirectoryRecord.h" - -void clear_buffer() { - int c; - while ((c = getchar()) != '\n' && c != EOF) { - } -} - -void append_record(Directory *directory) { - char phone_number[11]; - printf("Enter the phone number: "); - scanf("%s", phone_number); - clear_buffer(); - - char name[21]; - printf("Enter the name: "); - scanf("%s", name); - clear_buffer(); - - char surname[21]; - printf("Enter the surname: "); - scanf("%s", surname); - clear_buffer(); - - printf("Enter the birth date (Y-m-d): "); - // TODO : check more - int birth_date_year, birth_date_month, birth_date_day; - scanf("%d-%d-%d", &birth_date_year, &birth_date_month, &birth_date_day); - clear_buffer(); - - printf("\nIs the information entered correct? (Y/n) "); - - char choice = getchar(); - if (choice != '\n') { - getchar(); - } - - if (choice == 'n') { - printf("\n===>The procedure has been cancelled.\n"); - } else { - DirectoryRecord *record = DirectoryRecord_init(false, phone_number, name, surname, birth_date_year, birth_date_month, birth_date_day); - - if (Directory_append(directory, record)) { - printf("\n===>The record has been saved in the directory.\n"); - } else { - printf("\n===>This phone number is already associated with a record. The record has not been saved.\n"); - } - - DirectoryRecord_destroy(&record); - } -} - -void search_record(Directory *directory) { - printf("Enter the phone number that corresponds to the record you are looking for: "); - // TODO : crash phone number overflow - char phone_number[11]; - scanf("%s", phone_number); - clear_buffer(); - DirectoryRecord *record = Directory_search(directory, phone_number); - printf("\n"); - - if (record == NULL) { - printf("===>No records were found for this phone number.\n"); - } else { - printf("========================\n"); - DirectoryRecord_print(record); - DirectoryRecord_destroy(&record); - printf("========================\n"); - } -} - -int main() { - Directory *directory = Directory_init("directory_database"); - - while (true) { - printf("Enter 1 to add a member.\n"); - printf("Enter 2 to search for a member via their phone number.\n"); - printf("Enter 3 to delete a member.\n"); - printf("Enter 4 to display all members.\n"); - printf("Enter 5 to exit the program.\n"); - printf("What do you want to do? "); - int action; - scanf("%d", &action); - clear_buffer(); - - if (action < 1 || action > 5) { - system("clear"); - continue; - } - - if (action == 5) { - break; - } - - printf("\n"); - - switch (action) { - case 1: - append_record(directory); - break; - case 2: - search_record(directory); - break; - case 3: - break; - case 4: - Directory_print(directory); - break; - } - - printf("\nPress enter to continue..."); - getchar(); - system("clear"); - } - - Directory_destroy(&directory); - return EXIT_SUCCESS; -} diff --git a/b.c b/b.c new file mode 100644 index 0000000000000000000000000000000000000000..c06cf8fb51c83a64ad2f25512fc841cd0f1f772c --- /dev/null +++ b/b.c @@ -0,0 +1,57 @@ +#include <assert.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> + +#include "BPTree.h" + +int main() { + BPTreeNode *root = BPTree_init(2); + + uint64_t input[] = {8, 12, 11, 47, 22, 95, 86, 40, 33, 78, 28, 5, 75, 88, 21, 56, 82, 51, 93, 66, 48, 70, 57, 65, 35, 4, 60, 41, 49, 55, 68, 72, 23, 31, 30, 42, 18, 87, 24, 58}; + IntegerArray *keys = IntegerArray_init(40); + for (int i = 0; i < 30; i++) { + IntegerArray_append(keys, input[i]); + } + + IntegerArray_print(keys); + + for (int i = 0; i < keys->size; i++) { + BPTree_insert(root, keys->items[i], keys->items[i] * 1000); + } + + for (int i = 0; i < keys->size; i++) { + uint64_t data; + bool found = BPTree_search(root, keys->items[i], &data); + + assert(found == true); + assert(data == keys->items[i] * 1000); + } + + BPTree_delete(root, 65); + BPTree_delete(root, 57); + BPTree_delete(root, 47); + BPTree_delete(root, 28); + BPTree_delete(root, 51); + BPTree_insert(root, 100, 100 * 1000); + BPTree_delete(root, 48); + BPTree_delete(root, 41); + BPTree_delete(root, 60); + BPTree_delete(root, 5); + BPTree_delete(root, 8); + BPTree_delete(root, 21); + + BPTree_delete(root, 86); + BPTree_delete(root, 100); + BPTree_delete(root, 88); + BPTree_delete(root, 95); + BPTree_delete(root, 49); + BPTree_delete(root, 56); + BPTree_delete(root, 55); + + BPTree_print(root, 0); + + IntegerArray_destroy(&keys); + BPTree_destroy(&root); + return EXIT_SUCCESS; +} diff --git a/src/Directory.c b/src/Directory.c index 7d9a794a8960658c65b143b51d32460582fd246d..9bcc2049bfb403e0e743753283a7ad7de55402ce 100644 --- a/src/Directory.c +++ b/src/Directory.c @@ -51,10 +51,10 @@ static void rebuild_index(Directory *directory) { while (true) { uint64_t data_ptr = (uint64_t)ftell(fp); - uint8_t deleted; - fread(&deleted, 1, 1, fp); + uint8_t is_deleted; + fread(&is_deleted, 1, 1, fp); - if ((bool)deleted) { + if ((bool)is_deleted) { fseek(fp, DirectoryRecord_size_on_disk() - 1, SEEK_CUR); } else { char phone_number[PHONE_NUMBER_MAX_LENGTH]; @@ -72,12 +72,11 @@ static void rebuild_index(Directory *directory) { fclose(fp); } -Directory *Directory_init(char database_filename[100]) { +Directory *Directory_init(char database_filename[FILENAME_MAX_LENGTH]) { Directory *directory = (Directory *)malloc(sizeof(Directory)); strcpy(directory->database_filename, database_filename); directory->index = BPTree_init(DEFAULT_ORDER); rebuild_index(directory); - BPTree_print(directory->index, 0); return directory; } @@ -93,29 +92,34 @@ void Directory_print(Directory *directory) { if (fp == NULL) { printf("===>The directory is empty.\n"); + return; } long file_size = get_file_size(fp); printf("========================\n"); + int i = 0; while (true) { ByteArray *byte_array = ByteArray_init(DirectoryRecord_size_on_disk()); fread(byte_array->items, 1, DirectoryRecord_size_on_disk(), fp); byte_array->size = DirectoryRecord_size_on_disk(); + bool is_deleted = (bool)byte_array->items[0]; - if (!(bool)byte_array->items[0]) { + if (!is_deleted) { DirectoryRecord *record = ByteArray_to_DirectoryRecord(byte_array); + if (i != 0) { + printf("------------------------\n"); + } DirectoryRecord_print(record); DirectoryRecord_destroy(&record); + i++; } ByteArray_destroy(&byte_array); if (ftell(fp) == file_size) { break; - } else if (!(bool)byte_array->items[0]) { - printf("------------------------\n"); } } @@ -131,7 +135,7 @@ bool Directory_append(Directory *directory, DirectoryRecord *record) { // Writes the record to the file. FILE *fp; - fp = fopen(directory->database_filename, "a+b"); + fp = fopen(directory->database_filename, "ab"); if (fp == NULL) { exit(EXIT_FAILURE); @@ -171,3 +175,25 @@ DirectoryRecord *Directory_search(Directory *directory, char phone_number[11]) { return NULL; } + +bool Directory_delete(Directory *directory, char phone_number[11]) { + uint64_t data_ptr; + if (BPTree_search(directory->index, hash_string(phone_number), &data_ptr)) { + FILE *fp; + fp = fopen(directory->database_filename, "r+b"); + + if (fp == NULL) { + exit(EXIT_FAILURE); + } + + fseek(fp, data_ptr, SEEK_SET); + uint8_t is_deleted = (uint8_t) true; + fwrite(&is_deleted, 1, 1, fp); + fclose(fp); + + BPTree_delete(directory->index, hash_string(phone_number)); + return true; + } + + return false; +} diff --git a/src/Directory.h b/src/Directory.h index d6113b35c91493dfc419fc98c43b84211e2848a4..5b30b2514c2d23e3cb267244b8819262f8cddc70 100644 --- a/src/Directory.h +++ b/src/Directory.h @@ -5,16 +5,18 @@ #include "BPTree.h" #define DEFAULT_ORDER 2 +#define FILENAME_MAX_LENGTH 100 typedef struct Directory { - char database_filename[100]; + char database_filename[FILENAME_MAX_LENGTH]; BPTreeNode *index; } Directory; -Directory *Directory_init(char database_filename[100]); +Directory *Directory_init(char database_filename[FILENAME_MAX_LENGTH]); void Directory_destroy(Directory **directory); void Directory_print(Directory *directory); bool Directory_append(Directory *directory, DirectoryRecord *record); DirectoryRecord *Directory_search(Directory *directory, char phone_number[11]); +bool Directory_delete(Directory *directory, char phone_number[11]); #endif diff --git a/src/DirectoryRecord.c b/src/DirectoryRecord.c index 3ab7027cfe774ce5630200f8fe3170170daa13b2..bc3b558f7260e4e820b38c708cf7d5d29f0dd345 100644 --- a/src/DirectoryRecord.c +++ b/src/DirectoryRecord.c @@ -17,9 +17,9 @@ int DirectoryRecord_size_on_disk() { return size; } -DirectoryRecord *DirectoryRecord_init(bool deleted, char phone_number[PHONE_NUMBER_MAX_LENGTH], char name[NAME_MAX_LENGTH], char surname[SURNAME_MAX_LENGTH], int birth_date_year, int birth_date_month, int birth_date_day) { +DirectoryRecord *DirectoryRecord_init(bool is_deleted, char phone_number[PHONE_NUMBER_MAX_LENGTH], char name[NAME_MAX_LENGTH], char surname[SURNAME_MAX_LENGTH], int birth_date_year, int birth_date_month, int birth_date_day) { DirectoryRecord *record = (DirectoryRecord *)malloc(sizeof(DirectoryRecord)); - record->deleted = deleted; + record->is_deleted = is_deleted; memset(record->phone_number, 0, PHONE_NUMBER_MAX_LENGTH); strcpy(record->phone_number, phone_number); memset(record->name, 0, NAME_MAX_LENGTH); @@ -47,7 +47,7 @@ void DirectoryRecord_print(DirectoryRecord *record) { ByteArray *DirectoryRecord_to_ByteArray(DirectoryRecord *record) { int capacity = DirectoryRecord_size_on_disk(); ByteArray *array = ByteArray_init(capacity); - ByteArray_append(array, (uint8_t)record->deleted); + ByteArray_append(array, (uint8_t)record->is_deleted); for (int j = 0; j < PHONE_NUMBER_MAX_LENGTH_WITHOUT_NULL_CHARACTER; j++) { ByteArray_append(array, (uint8_t)record->phone_number[j]); @@ -74,7 +74,7 @@ ByteArray *DirectoryRecord_to_ByteArray(DirectoryRecord *record) { DirectoryRecord *ByteArray_to_DirectoryRecord(ByteArray *byte_array) { int i = 0; - bool deleted = (bool)byte_array->items[i]; + bool is_deleted = (bool)byte_array->items[i]; i++; char phone_number[PHONE_NUMBER_MAX_LENGTH]; @@ -105,5 +105,5 @@ DirectoryRecord *ByteArray_to_DirectoryRecord(ByteArray *byte_array) { int birth_date_month = (int)byte_array->items[i + 2]; int birth_date_day = (int)byte_array->items[i + 3]; - return DirectoryRecord_init(deleted, phone_number, name, surname, birth_date_year, birth_date_month, birth_date_day); + return DirectoryRecord_init(is_deleted, phone_number, name, surname, birth_date_year, birth_date_month, birth_date_day); } diff --git a/src/DirectoryRecord.h b/src/DirectoryRecord.h index 2e84d1b27700bede8ce396e68d8554c457f1ace5..9c923dd2ce66be257470564b6eb6c4e331ed8d2a 100644 --- a/src/DirectoryRecord.h +++ b/src/DirectoryRecord.h @@ -18,7 +18,7 @@ #define BIRTH_DATE_SIZE_IN_BYTES 4 typedef struct DirectoryRecord { - bool deleted; + bool is_deleted; char phone_number[PHONE_NUMBER_MAX_LENGTH]; char name[NAME_MAX_LENGTH]; char surname[SURNAME_MAX_LENGTH]; @@ -29,7 +29,7 @@ typedef struct DirectoryRecord { int DirectoryRecord_size_on_disk(); -DirectoryRecord *DirectoryRecord_init(bool deleted, char phone_number[PHONE_NUMBER_MAX_LENGTH], char name[NAME_MAX_LENGTH], char surname[SURNAME_MAX_LENGTH], int birth_date_year, int birth_date_month, int birth_date_day); +DirectoryRecord *DirectoryRecord_init(bool is_deleted, char phone_number[PHONE_NUMBER_MAX_LENGTH], char name[NAME_MAX_LENGTH], char surname[SURNAME_MAX_LENGTH], int birth_date_year, int birth_date_month, int birth_date_day); void DirectoryRecord_destroy(DirectoryRecord **record); void DirectoryRecord_print(DirectoryRecord *record); ByteArray *DirectoryRecord_to_ByteArray(DirectoryRecord *record); diff --git a/src/main.c b/src/main.c index c06cf8fb51c83a64ad2f25512fc841cd0f1f772c..a361faf74b42b8d924c80858edc0ce1acfc36f19 100644 --- a/src/main.c +++ b/src/main.c @@ -1,57 +1,159 @@ -#include <assert.h> -#include <stdbool.h> +// CAUTION : validation des entrées #include <stdio.h> #include <stdlib.h> -#include "BPTree.h" +#include "Directory.h" +#include "DirectoryRecord.h" -int main() { - BPTreeNode *root = BPTree_init(2); +void clear_buffer() { + int c; + while ((c = getchar()) != '\n' && c != EOF) { + } +} + +void append_record(Directory *directory) { + char phone_number[11]; + printf("Enter the phone number: "); + scanf("%s", phone_number); + clear_buffer(); + + char name[21]; + printf("Enter the name: "); + scanf("%s", name); + clear_buffer(); + + char surname[21]; + printf("Enter the surname: "); + scanf("%s", surname); + clear_buffer(); + + printf("Enter the birth date (Y-m-d): "); + // TODO : check more + int birth_date_year, birth_date_month, birth_date_day; + scanf("%d-%d-%d", &birth_date_year, &birth_date_month, &birth_date_day); + clear_buffer(); + + printf("\nIs the information entered correct? (Y/n) "); - uint64_t input[] = {8, 12, 11, 47, 22, 95, 86, 40, 33, 78, 28, 5, 75, 88, 21, 56, 82, 51, 93, 66, 48, 70, 57, 65, 35, 4, 60, 41, 49, 55, 68, 72, 23, 31, 30, 42, 18, 87, 24, 58}; - IntegerArray *keys = IntegerArray_init(40); - for (int i = 0; i < 30; i++) { - IntegerArray_append(keys, input[i]); + char choice = getchar(); + if (choice != '\n') { + getchar(); } - IntegerArray_print(keys); + if (choice == 'n') { + printf("\n===>The procedure has been cancelled.\n"); + } else { + DirectoryRecord *record = DirectoryRecord_init(false, phone_number, name, surname, birth_date_year, birth_date_month, birth_date_day); - for (int i = 0; i < keys->size; i++) { - BPTree_insert(root, keys->items[i], keys->items[i] * 1000); + if (Directory_append(directory, record)) { + printf("\n===>The record has been saved in the directory.\n"); + } else { + printf("\n===>This phone number is already associated with a record. The record has not been saved.\n"); + } + + DirectoryRecord_destroy(&record); } +} + +void search_record(Directory *directory) { + printf("Enter the phone number that corresponds to the record you are looking for: "); + // TODO : crash phone number overflow + char phone_number[11]; + scanf("%s", phone_number); + clear_buffer(); + DirectoryRecord *record = Directory_search(directory, phone_number); + printf("\n"); + + if (record == NULL) { + printf("===>No records were found for this phone number.\n"); + } else { + printf("========================\n"); + DirectoryRecord_print(record); + DirectoryRecord_destroy(&record); + printf("========================\n"); + } +} + +void delete_record(Directory *directory) { + printf("Enter the phone number that corresponds to the record you wish to delete: "); + + char phone_number[11]; + scanf("%s", phone_number); + clear_buffer(); + DirectoryRecord *record = Directory_search(directory, phone_number); + printf("\n"); + + if (record == NULL) { + printf("===>No records were found for this phone number.\n"); + } else { + printf("========================\n"); + DirectoryRecord_print(record); + DirectoryRecord_destroy(&record); + printf("========================\n"); + + printf("\nAre you sure you want to delete this record? (Y/n) "); + + char choice = getchar(); + if (choice != '\n') { + getchar(); + } + + if (choice == 'n') { + printf("\n===>The procedure has been cancelled.\n"); + } else { + Directory_delete(directory, phone_number); + printf("Delete done\n"); + } + } +} + +int main() { + Directory *directory = Directory_init("directory_database"); + + while (true) { + BPTree_print(directory->index, 0); + + printf("Enter 1 to add a member.\n"); + printf("Enter 2 to search for a member via their phone number.\n"); + printf("Enter 3 to delete a member.\n"); + printf("Enter 4 to display all members.\n"); + printf("Enter 5 to exit the program.\n"); + printf("What do you want to do? "); + int action; + scanf("%d", &action); + clear_buffer(); + + if (action < 1 || action > 5) { + system("clear"); + continue; + } + + if (action == 5) { + break; + } + + printf("\n"); - for (int i = 0; i < keys->size; i++) { - uint64_t data; - bool found = BPTree_search(root, keys->items[i], &data); + switch (action) { + case 1: + append_record(directory); + break; + case 2: + search_record(directory); + break; + case 3: + delete_record(directory); + break; + case 4: + Directory_print(directory); + break; + } - assert(found == true); - assert(data == keys->items[i] * 1000); + printf("\nPress enter to continue..."); + getchar(); + system("clear"); } - BPTree_delete(root, 65); - BPTree_delete(root, 57); - BPTree_delete(root, 47); - BPTree_delete(root, 28); - BPTree_delete(root, 51); - BPTree_insert(root, 100, 100 * 1000); - BPTree_delete(root, 48); - BPTree_delete(root, 41); - BPTree_delete(root, 60); - BPTree_delete(root, 5); - BPTree_delete(root, 8); - BPTree_delete(root, 21); - - BPTree_delete(root, 86); - BPTree_delete(root, 100); - BPTree_delete(root, 88); - BPTree_delete(root, 95); - BPTree_delete(root, 49); - BPTree_delete(root, 56); - BPTree_delete(root, 55); - - BPTree_print(root, 0); - - IntegerArray_destroy(&keys); - BPTree_destroy(&root); + Directory_destroy(&directory); return EXIT_SUCCESS; }