Exercices Langage C

Exercice 5 Langage C Corrigé S1

Système de Gestion d'un Réseau Social

Objectifs :

  1. Utiliser des listes chaînées ou des tableaux dynamiques.
  2. Travailler avec des structures imbriquées pour représenter les utilisateurs et les relations d'amitié.
  3. Manipuler des fichiers pour enregistrer et charger des données.
  4. Implémenter des algorithmes de recherche et de gestion de graphes (liens entre utilisateurs).

Énoncé : Développez un programme en C pour simuler un réseau social simplifié. Le réseau social permet aux utilisateurs de s'inscrire, de se lier d'amitié avec d'autres utilisateurs, de consulter leurs amis, et de recommander des amis en fonction des amis en commun.

Les utilisateurs : Chaque utilisateur est caractérisé par :

  • Un identifiant unique,
  • Un nom,
  • Une liste d'amis (ou un tableau dynamique d'amis).

Le programme doit afficher le menu suivant : 

------------------MENU------------------
1: Ajouter un utilisateur
2: Lier deux utilisateurs en tant qu'amis
3: Supprimer une amitié
4: Afficher la liste d'amis d'un utilisateur
5: Recommander des amis
6: Sauvegarder l'état du réseau social
7: Charger l'état du réseau social depuis un fichier
0: Quitter le programme
-----------------------------------------

Détails des options :

  • Option 1 (Ajouter un utilisateur) : Le programme demande un identifiant unique et un nom, puis crée un nouvel utilisateur sans amis. Si l'utilisateur existe déjà, une erreur est signalée.

  • Option 2 (Lier deux utilisateurs en tant qu'amis) : Le programme demande les identifiants de deux utilisateurs et les lie d'amitié s'ils existent. Une amitié est bidirectionnelle (si A est ami avec B, alors B est aussi ami avec A). Si un des utilisateurs n'existe pas, une erreur est signalée.

  • Option 3 (Supprimer une amitié) : Le programme demande les identifiants de deux utilisateurs et supprime leur amitié. Si l'un des utilisateurs n'existe pas ou s'ils ne sont pas amis, une erreur est signalée.

  • Option 4 (Afficher la liste d'amis d'un utilisateur) : Le programme demande l'identifiant de l'utilisateur et affiche la liste de ses amis. Si l'utilisateur n'a pas d'amis ou n'existe pas, une erreur est signalée.

  • Option 5 (Recommander des amis) : Le programme recommande des amis à un utilisateur en fonction du nombre d'amis en commun. Il affiche une liste des utilisateurs qui ne sont pas encore amis avec lui mais qui ont des amis en commun.

  • Option 6 (Sauvegarder l'état du réseau social) : Sauvegarde tous les utilisateurs et leurs amitiés dans un fichier binaire.

  • Option 7 (Charger l'état du réseau social) : Charge les utilisateurs et les amitiés depuis un fichier binaire.

Consignes :

  • Utiliser une structure Utilisateur pour stocker les informations des utilisateurs et leurs amis.
  • Implémenter les relations d'amitié avec des listes chaînées ou des tableaux dynamiques.
  • Recommander des amis en utilisant un algorithme de recherche pour trouver les amis en commun.
  • Gérer la sauvegarde et le chargement des utilisateurs et de leurs relations dans des fichiers binaires.

1. Définition des Structures

Vous aurez besoin de structures pour représenter les utilisateurs et leurs relations d'amitié.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_NOM 50
#define MAX_UTILISATEURS 100

typedef struct Utilisateur Utilisateur;

struct Utilisateur {
    int id;
    char nom[MAX_NOM];
    Utilisateur** amis; // Liste des amis (tableau dynamique de pointeurs vers Utilisateur)
    int nb_amis; // Nombre d'amis
    int capacite_amis; // Capacité actuelle du tableau d'amis
};

typedef struct {
    Utilisateur* utilisateurs[MAX_UTILISATEURS];
    int nb_utilisateurs;
} RéseauSocial;

2. Prototypes des Fonctions

Déclarez les prototypes des fonctions nécessaires pour les différentes opérations.

void afficher_menu();
void ajouter_utilisateur(RéseauSocial* réseau);
void lier_utilisateurs(RéseauSocial* réseau);
void supprimer_amitié(RéseauSocial* réseau);
void afficher_amis(RéseauSocial* réseau);
void recommander_amis(RéseauSocial* réseau);
void sauvegarder_réseau(RéseauSocial* réseau);
void charger_réseau(RéseauSocial* réseau);
Utilisateur* trouver_utilisateur(RéseauSocial* réseau, int id);
void ajouter_ami(Utilisateur* utilisateur, Utilisateur* ami);
void supprimer_ami(Utilisateur* utilisateur, Utilisateur* ami);
void recommander_amitié(Utilisateur* utilisateur);

3. Fonctions de Gestion des Utilisateurs

Ajouter un Utilisateur

void ajouter_utilisateur(RéseauSocial* réseau) {
    int id;
    char nom[MAX_NOM];
    
    printf("Entrez l'identifiant de l'utilisateur : ");
    scanf("%d", &id);
    getchar(); // Consommer le '\n'
    
    if (trouver_utilisateur(réseau, id)) {
        printf("L'utilisateur avec cet identifiant existe déjà.\n");
        return;
    }
    
    printf("Entrez le nom de l'utilisateur : ");
    fgets(nom, MAX_NOM, stdin);
    nom[strcspn(nom, "\n")] = 0;
    
    Utilisateur* nouvel_utilisateur = malloc(sizeof(Utilisateur));
    nouvel_utilisateur->id = id;
    strcpy(nouvel_utilisateur->nom, nom);
    nouvel_utilisateur->amis = malloc(10 * sizeof(Utilisateur*)); // Initialiser avec une capacité de 10
    nouvel_utilisateur->nb_amis = 0;
    nouvel_utilisateur->capacite_amis = 10;
    
    réseau->utilisateurs[réseau->nb_utilisateurs++] = nouvel_utilisateur;
    printf("Utilisateur ajouté avec succès.\n");
}

Trouver un Utilisateur

Utilisateur* trouver_utilisateur(RéseauSocial* réseau, int id) {
    for (int i = 0; i < réseau->nb_utilisateurs; i++) {
        if (réseau->utilisateurs[i]->id == id) {
            return réseau->utilisateurs[i];
        }
    }
    return NULL;
}

Ajouter un Ami

void ajouter_ami(Utilisateur* utilisateur, Utilisateur* ami) {
    if (utilisateur->nb_amis == utilisateur->capacite_amis) {
        utilisateur->capacite_amis *= 2;
        utilisateur->amis = realloc(utilisateur->amis, utilisateur->capacite_amis * sizeof(Utilisateur*));
    }
    utilisateur->amis[utilisateur->nb_amis++] = ami;
}

Supprimer un Ami

void supprimer_ami(Utilisateur* utilisateur, Utilisateur* ami) {
    int index = -1;
    for (int i = 0; i < utilisateur->nb_amis; i++) {
        if (utilisateur->amis[i] == ami) {
            index = i;
            break;
        }
    }
    if (index != -1) {
        for (int i = index; i < utilisateur->nb_amis - 1; i++) {
            utilisateur->amis[i] = utilisateur->amis[i + 1];
        }
        utilisateur->nb_amis--;
    }
}

4. Fonctionnalités

Lier Deux Utilisateurs en Tant qu'Amis

void lier_utilisateurs(RéseauSocial* réseau) {
    int id1, id2;
    printf("Entrez l'identifiant du premier utilisateur : ");
    scanf("%d", &id1);
    printf("Entrez l'identifiant du deuxième utilisateur : ");
    scanf("%d", &id2);

    Utilisateur* utilisateur1 = trouver_utilisateur(réseau, id1);
    Utilisateur* utilisateur2 = trouver_utilisateur(réseau, id2);

    if (utilisateur1 && utilisateur2 && utilisateur1 != utilisateur2) {
        ajouter_ami(utilisateur1, utilisateur2);
        ajouter_ami(utilisateur2, utilisateur1);
        printf("Amitié ajoutée.\n");
    } else {
        printf("Erreur : l'un ou les deux utilisateurs n'existent pas ou les identifiants sont identiques.\n");
    }
}

Supprimer une Amitié

void supprimer_amitié(RéseauSocial* réseau) {
    int id1, id2;
    printf("Entrez l'identifiant du premier utilisateur : ");
    scanf("%d", &id1);
    printf("Entrez l'identifiant du deuxième utilisateur : ");
    scanf("%d", &id2);

    Utilisateur* utilisateur1 = trouver_utilisateur(réseau, id1);
    Utilisateur* utilisateur2 = trouver_utilisateur(réseau, id2);

    if (utilisateur1 && utilisateur2) {
        supprimer_ami(utilisateur1, utilisateur2);
        supprimer_ami(utilisateur2, utilisateur1);
        printf("Amitié supprimée.\n");
    } else {
        printf("Erreur : l'un ou les deux utilisateurs n'existent pas.\n");
    }
}

Afficher la Liste d'Amis d'un Utilisateur

void afficher_amis(RéseauSocial* réseau) {
    int id;
    printf("Entrez l'identifiant de l'utilisateur : ");
    scanf("%d", &id);

    Utilisateur* utilisateur = trouver_utilisateur(réseau, id);
    if (utilisateur) {
        printf("Liste des amis de %s :\n", utilisateur->nom);
        for (int i = 0; i < utilisateur->nb_amis; i++) {
            printf("  - %s\n", utilisateur->amis[i]->nom);
        }
    } else {
        printf("Utilisateur non trouvé.\n");
    }
}

Recommander des Amis

void recommander_amitié(Utilisateur* utilisateur) {
    printf("Recommandations pour %s :\n", utilisateur->nom);

    for (int i = 0; i < utilisateur->nb_amis; i++) {
        Utilisateur* ami = utilisateur->amis[i];
        for (int j = 0; j < ami->nb_amis; j++) {
            Utilisateur* ami_ami = ami->amis[j];
            if (ami_ami != utilisateur && !trouver_utilisateur(utilisateur, ami_ami->id)) {
                int commun = 0;
                for (int k = 0; k < utilisateur->nb_amis; k++) {
                    if (trouver_utilisateur(ami, utilisateur->amis[k]->id)) {
                        commun++;
                    }
                }
                if (commun > 0) {
                    printf("  - %s (communs : %d)\n", ami_ami->nom, commun);
                }
            }
        }
    }
}

Sauvegarder l'État du Réseau Social

void sauvegarder_réseau(RéseauSocial* réseau) {
    FILE* fichier = fopen("réseau_social.dat", "wb");
    if (fichier == NULL) {
        printf("Erreur d'ouverture du fichier.\n");
        return;
    }

    fwrite(&réseau->nb_utilisateurs, sizeof(int), 1, fichier);
    for (int i = 0; i < réseau->nb_utilisateurs; i++) {
        Utilisateur* utilisateur = réseau->utilisateurs[i];
        fwrite(&utilisateur->id, sizeof(int), 1, fichier);
        fwrite(utilisateur->nom, sizeof(char), MAX_NOM, fichier);
        fwrite(&utilisateur->nb_amis, sizeof(int), 1, fichier);
        for (int j = 0; j < utilisateur->nb_amis; j++) {
            fwrite(&utilisateur->amis[j]->id, sizeof(int), 1, fichier);
        }
    }

    fclose(fichier);
    printf("État du réseau social sauvegardé.\n");
}

Charger l'État du Réseau Social

void charger_réseau(RéseauSocial* réseau) {
    FILE* fichier = fopen("réseau_social.dat", "rb");
    if (fichier == NULL) {
        printf("Erreur d'ouverture du fichier.\n");
        return;
    }

    fread(&réseau->nb_utilisateurs, sizeof(int), 1, fichier);
    for (int i = 0; i < réseau->nb_utilisateurs; i++) {
        Utilisateur* utilisateur = malloc(sizeof(Utilisateur));
        fread(&utilisateur->id, sizeof(int), 1, fichier);
        fread(utilisateur->nom, sizeof(char), MAX_NOM, fichier);
        fread(&utilisateur->nb_amis, sizeof(int), 1, fichier);
        utilisateur->amis = malloc(utilisateur->nb_amis * sizeof(Utilisateur*));
        for (int j = 0; j < utilisateur->nb_amis; j++) {
            int id_ami;
            fread(&id_ami, sizeof(int), 1, fichier);
            utilisateur->amis[j] = trouver_utilisateur(réseau, id_ami);
        }
        réseau->utilisateurs[i] = utilisateur;
    }

    fclose(fichier);
    printf("État du réseau social chargé.\n");
}

5. Fonction Menu

Le menu principal du programme pour naviguer entre les différentes options.

void afficher_menu() {
    printf("------------------MENU------------------\n");
    printf("1: Ajouter un utilisateur\n");
    printf("2: Lier deux utilisateurs en tant qu'amis\n");
    printf("3: Supprimer une amitié\n");
    printf("4: Afficher la liste d'amis d'un utilisateur\n");
    printf("5: Recommander des amis\n");
    printf("6: Sauvegarder l'état du réseau social\n");
    printf("7: Charger l'état du réseau social depuis un fichier\n");
    printf("0: Quitter le programme\n");
    printf("-----------------------------------------\n");
}

int main() {
    RéseauSocial réseau = {0};

    int choix;
    do {
        afficher_menu();
        printf("Votre choix : ");
        scanf("%d", &choix);
        getchar(); // Consommer le '\n'
        
        switch (choix) {
            case 1:
                ajouter_utilisateur(&réseau);
                break;
            case 2:
                lier_utilisateurs(&réseau);
                break;
            case 3:
                supprimer_amitié(&réseau);
                break;
            case 4:
                afficher_amis(&réseau);
                break;
            case 5:
                recommander_amis(&réseau);
                break;
            case 6:
                sauvegarder_réseau(&réseau);
                break;
            case 7:
                charger_réseau(&réseau);
                break;
            case 0:
                printf("Quitter le programme.\n");
                break;
            default:
                printf("Choix invalide.\n");
        }
    } while (choix != 0);

    return 0;
}

 

Ajouter un commentaire

Veuillez vous connecter pour ajouter un commentaire.

Pas encore de commentaires.