Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,19 @@ add_executable(Mini_Database
student.c
student.h
undo_stack.c
undo_stack.h)
undo_stack.h
arbres_binaire.c
arbres_binaire.h)

# Executable pour les tests
add_executable(Test_Student
test_student.c
student.c
student.h
undo_stack.c
undo_stack.h)
undo_stack.h
arbres_binaire.c
arbres_binaire.h)

# Activer CTest
enable_testing()
Expand Down
57 changes: 57 additions & 0 deletions arbres_binaire.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include <stdlib.h>
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arbres_binaire.c starts with a UTF-8 BOM before the #include ("#include..."). This can break compilation on some toolchains; remove the BOM so the file begins directly with #include.

Suggested change
#include <stdlib.h>
#include <stdlib.h>

Copilot uses AI. Check for mistakes.
#include <string.h>
#include <stdio.h>
#include "arbres_binaire.h"

ab_node_student *create_ab_node(student *student) {
if (student == NULL) return NULL;

ab_node_student *node = (ab_node_student *) malloc(sizeof(ab_node_student));
if (node == NULL) {
printf("Erreur d'allocation memoire!\n");
return NULL;
}

node->std = student;

node->filsd = NULL;
node->filsg = NULL;

return node;
}

ab_racine_student *create_ab_racine() {
ab_racine_student *racine = (ab_racine_student *) malloc(sizeof(ab_racine_student));
if (racine == NULL) {
printf("Erreur d'allocation memoire!\n");
return NULL;
}
racine->racine = NULL;
return racine;
}

ab_node_student *insert_recursive_worker(ab_node_student *currant, ab_node_student *new_node) {
if (currant == NULL) return new_node;

if (new_node->std->moyenne < currant->std->moyenne) {
currant->filsg = insert_recursive_worker(currant->filsg, new_node);
} else {
currant->filsd = insert_recursive_worker(currant->filsd, new_node);
}
return currant;
}
Comment on lines +33 to +42
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

insert_recursive_worker() is not declared in the header but is currently a global symbol. Since it is only used inside arbres_binaire.c, mark it static to avoid exporting an unintended API surface and reduce the risk of symbol collisions.

Copilot uses AI. Check for mistakes.

void insert_bst(ab_racine_student *racine, ab_node_student *node) {
if (racine == NULL || node == NULL) return;

racine->racine = insert_recursive_worker(racine->racine, node);
}

void free_bst_nodes(ab_node_student *node) {
if (node == NULL) return;

free_bst_nodes(node->filsg);
free_bst_nodes(node->filsd);

free(node);
}
25 changes: 25 additions & 0 deletions arbres_binaire.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef MINI_DATABASE_ARBRES_BINAIRE_H
#define MINI_DATABASE_ARBRES_BINAIRE_H
#include "undo_stack.h"
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arbres_binaire.h includes undo_stack.h, but the tree API only needs the student type. Including undo_stack.h creates unnecessary coupling and can introduce circular dependencies; include student.h (or forward-declare struct student) instead and keep undo stack concerns separate.

Suggested change
#include "undo_stack.h"
#include "student.h"

Copilot uses AI. Check for mistakes.

// structure de node d'arbre
typedef struct ab_node_student {
student *std;
struct ab_node_student *filsg;
struct ab_node_student *filsd;
} ab_node_student;

// structure de racine d'arbre
typedef struct ab_racine_student {
ab_node_student *racine;
} ab_racine_student;

ab_node_student *create_ab_node(student *student);
void insert_bst(ab_racine_student *racine, ab_node_student *node);

ab_racine_student *create_ab_racine();

void afficher_arbres_trie(ab_racine_student *racine);

void free_bst_nodes(ab_node_student *node);
#endif //MINI_DATABASE_ARBRES_BINAIRE_H
25 changes: 21 additions & 4 deletions main.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "arbres_binaire.h"
#include "undo_stack.h"
// #include <windows.h> // pour les Accents
/**
Expand All @@ -15,11 +17,9 @@ int main() {
list_student *my_db = creat_list_student();
UndoStack *my_stack = create_undo_stack();
load_database(my_db, "my_data.db");

int choice = 0;
char cne_buffer[15];


do {
printf("\n=== MINI DATABASE MENU ===\n");
printf("1. Ajouter un etudiant\n");
Expand Down Expand Up @@ -87,11 +87,28 @@ int main() {
search_student_by_cne(my_db, cne_buffer);
break;
case 6:
sort_students_by_grade(my_db);
// sort_students_by_grade(my_db);
if (my_db->tete == NULL) {
printf("La Base de donnee est vide, rien a trier.\n");
break;
}

ab_racine_student *temp_tree = create_ab_racine();
// temp_tree->racine = NULL;

student *current_s = my_db->tete;
while (current_s != NULL) {
ab_node_student *new_node = create_ab_node(current_s);
insert_bst(temp_tree, new_node);
current_s = current_s->next;
}

afficher_arbres_trie(temp_tree);
free_bst_nodes(temp_tree->racine);
break;
Comment on lines +96 to 108
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

case 6: temp_tree is never freed, so each sort operation leaks memory. Also create_ab_racine() can return NULL; in that case free_bst_nodes(temp_tree->racine) will dereference NULL. Check temp_tree != NULL before use, and free(temp_tree) after freeing its nodes (or add a helper that frees both root and wrapper).

Copilot uses AI. Check for mistakes.
case 7:
printf("\nATTENTION: Cette action supprimera tous les etudiants!\n");
printf("NB : les etudiants apres la suppression n'ajoute pas dans Historique!!!");
printf("NB : les etudiants apres la suppression n'ajoute pas dans Historique!!!\n");
printf("Etes-vous sur? (1=Oui, 0=Non): ");
int confirm;
scanf("%d", &confirm);
Expand Down
Binary file modified myApp
Binary file not shown.
60 changes: 60 additions & 0 deletions student.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <string.h>
#include <stdio.h>

#include "arbres_binaire.h"
#include "undo_stack.h"
/**
* @brief Crée et initialise une liste d'étudiants vide.
Expand Down Expand Up @@ -90,6 +91,33 @@ void display_all_student(list_student *list_student) {
}
}

void display_student(list_student *list_student, char *cne) {
if (list_student == NULL || list_student->tete == NULL) {
printf("la Base de donnee et vide!!!\n");
}
int trouver = 0;
student *courent = list_student->tete;
Comment on lines +94 to +99
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

display_student(): after printing that the database is empty, the function continues and dereferences list_student->tete, which will crash when list_student==NULL. Add an early return when list_student==NULL or list_student->tete==NULL (and consider validating cne as well).

Copilot uses AI. Check for mistakes.
while (courent != NULL && strcmp(courent->CNE, cne) != 0) {
trouver = 1;
printf("\n");
printf("+--------------------------------------------+\n");
printf("| INFORMATION ETUDIANT |\n"); // J'ai ajouté %-2d pour l'alignement
printf("+--------------------------------------------+\n");
printf("| CNE : %-25.25s |\n", courent->CNE);
printf("| Nom : %-25.25s |\n", courent->nom);
printf("| Prenom : %-25.25s |\n", courent->prenom);
printf("| Date Naissance : %02d/%02d/%-19d |\n", courent->date_naissance.jour,
courent->date_naissance.mois, courent->date_naissance.annee);
printf("| Filiere : %-25.25s |\n", courent->filiere);
printf("| Moyenne : %-25.2f |\n", courent->moyenne);
printf("+--------------------------------------------+\n");
courent = courent->next;
}
if (trouver == 0) {
printf("etudiant n'est pas trouver!!!\n");
}
Comment on lines +100 to +118
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

display_student(): the search loop is inverted—it's printing students while strcmp(...) != 0 and sets trouver=1 for non-matches, so it prints the wrong records and reports "not found" when the first element matches. Iterate through the list until a match is found; only print when strcmp(...)==0 and set trouver when a match is found (or break and handle "not found" after the loop).

Copilot uses AI. Check for mistakes.
}

/**
* @brief Supprime un étudiant de la liste en utilisant son CNE.
*
Expand Down Expand Up @@ -523,3 +551,35 @@ void sort_students_by_grade(list_student *list) {

printf("Liste triee par moyenne avec succes.\n");
}

static void display_student_arbre(student *student) {
printf("+--------------------------------------------+\n");
printf("| INFORMATION ETUDIANT |\n"); // J'ai ajouté %-2d pour l'alignement
printf("+--------------------------------------------+\n");
printf("| CNE : %-25.25s |\n", student->CNE);
printf("| Nom : %-25.25s |\n", student->nom);
printf("| Prenom : %-25.25s |\n", student->prenom);
printf("| Date Naissance : %02d/%02d/%-19d |\n", student->date_naissance.jour,
student->date_naissance.mois, student->date_naissance.annee);
printf("| Filiere : %-25.25s |\n", student->filiere);
printf("| Moyenne : %-25.2f |\n", student->moyenne);
printf("+--------------------------------------------+\n");
}

static void sort_by_arbre_recursive(ab_node_student *node) {
if (node != NULL) {
sort_by_arbre_recursive(node->filsd);
display_student_arbre(node->std);
sort_by_arbre_recursive(node->filsg);
}
}

void afficher_arbres_trie(ab_racine_student *racine) {
if (racine == NULL || racine->racine == NULL) {
printf("L'arbre est vide.\n");
return;
}
printf("\n=== Liste des etudiants triee par moyenne (Decroissant) ===\n");
sort_by_arbre_recursive(racine->racine);
printf("===========================================================\n");
}
5 changes: 5 additions & 0 deletions student.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,14 @@ student *creat_student(); // Crée et initialise un nouvel étudiant.

void display_all_student(list_student *list_student); // Affiche les informations de tous les étudiants de la liste.

void display_student(list_student *list_student, char *cne);

void save_database(list_student *list, char *filename); // Sauvegarde la liste des étudiants dans un fichier.


void load_database(list_student *list, char *filename); // Charge la liste des étudiants à partir d'un fichier.


void search_student_by_cne(list_student *list, char *cne);

void delete_all_students(list_student *list);
Expand All @@ -52,4 +56,5 @@ student *get_middle(student *head);
student *merge_sorted_lists(student *left, student *right);

student *merge_sort_recursive(student *head);

#endif //MINI_DATABASE_STUDENT_H
Loading