Exercices Langage C

Exercice 3 Langage C Corrigé S1

Gestion d'un Système de Réservations d'Hôtel

Objectifs :

  1. Travailler avec plusieurs structures de données en C.
  2. Manipuler des fichiers pour enregistrer et charger des données.
  3. Utiliser des algorithmes pour rechercher et trier les données.
  4. Manipuler des dates en C.

Énoncé : Créez un programme en C pour gérer un système de réservation d'hôtel. L'hôtel a plusieurs chambres et chaque chambre peut être réservée par des clients pour une durée déterminée.

Les chambres : Chaque chambre est caractérisée par :

  • Un numéro de chambre,
  • Un type de chambre (simple, double, suite),
  • Un prix par nuit.

Les clients : Chaque client est caractérisé par :

  • Un nom,
  • Un prénom,
  • Une date d'arrivée,
  • Une date de départ.

Le programme doit afficher un menu avec les options suivantes :

------------------MENU------------------
1: Ajouter une nouvelle réservation
2: Annuler une réservation
3: Afficher les réservations en cours
4: Rechercher une réservation par nom de client
5: Afficher la liste des chambres disponibles
6: Sauvegarder les réservations dans un fichier
0: Quitter le programme
-----------------------------------------

Détails des options :

  • Ajouter une nouvelle réservation : Le programme demande au client de saisir son nom, son prénom, la date d'arrivée, la date de départ, et choisit une chambre disponible. Le système vérifie que la chambre est disponible pour les dates données avant d'ajouter la réservation.

  • Annuler une réservation : Le programme demande le nom du client et annule sa réservation si elle existe.

  • Afficher les réservations en cours : Affiche la liste des clients qui ont réservé une chambre ainsi que leurs dates de séjour.

  • Rechercher une réservation par nom de client : Le programme affiche la réservation d'un client donné (nom/prénom).

  • Afficher la liste des chambres disponibles : Affiche la liste des chambres disponibles pour une période donnée (date de début et date de fin) spécifiée par l'utilisateur.

  • Sauvegarder les réservations : Enregistre toutes les réservations dans un fichier binaire ou texte, avec la possibilité de recharger les données lors de la relance du programme.

Consignes avancées :

  • Utiliser des structures de données pour représenter les clients, les chambres et les réservations.
  • Implémenter des algorithmes de recherche pour trouver les chambres disponibles en fonction des dates.
  • Utiliser des fichiers pour sauvegarder l'état du système de réservation.
  • Gérer les chevauchements de dates pour les réservations.
  • Utiliser des fonctions pour manipuler les dates (par exemple, les structures tm de la bibliothèque <time.h>).

Ces deux exercices couvrent des concepts fondamentaux et avancés en C, et ils permettent aux étudiants de pratiquer à la fois la gestion de la mémoire, les algorithmes de recherche/tri, ainsi que la manipulation de fichiers et de structures de données complexes.

1. Définition des Structures

Définissez les structures pour représenter les chambres, les clients, et les réservations.

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

#define MAX_NOM 50
#define MAX_TYPE_CHAMBRE 20
#define MAX_RESERVATIONS 100

typedef struct {
    int numero;
    char type[MAX_TYPE_CHAMBRE];
    float prix_par_nuit;
    int reservee; // 0 pour disponible, 1 pour réservée
} Chambre;

typedef struct {
    char nom[MAX_NOM];
    char prenom[MAX_NOM];
    struct tm date_arrivee;
    struct tm date_depart;
} Client;

typedef struct {
    Chambre chambre;
    Client client;
} Reservation;

2. Prototypes des Fonctions

Les prototypes des fonctions nécessaires au programme :

void afficher_menu();
void ajouter_reservation(Chambre* chambres, int nb_chambres, Reservation* reservations, int* nb_reservations);
void annuler_reservation(Reservation* reservations, int* nb_reservations);
void afficher_reservations(Reservation* reservations, int nb_reservations);
void rechercher_reservation(Reservation* reservations, int nb_reservations);
void afficher_chambres_disponibles(Chambre* chambres, int nb_chambres, Reservation* reservations, int nb_reservations);
void sauvegarder_reservations(Reservation* reservations, int nb_reservations);
void charger_reservations(Reservation* reservations, int* nb_reservations);

3. Fonction Principale

La fonction principale gère le menu et les options.

int main() {
    int choix;
    int nb_chambres = 5; // Exemple : nombre initial de chambres
    int nb_reservations = 0;
    
    Chambre chambres[] = {
        {101, "Simple", 50.0, 0},
        {102, "Double", 80.0, 0},
        {103, "Suite", 120.0, 0},
        {104, "Simple", 50.0, 0},
        {105, "Double", 80.0, 0}
    };
    
    Reservation* reservations = malloc(MAX_RESERVATIONS * sizeof(Reservation));
    if (reservations == NULL) {
        printf("Erreur d'allocation mémoire\n");
        return 1;
    }

    do {
        afficher_menu();
        printf("Choisissez une option : ");
        scanf("%d", &choix);
        getchar(); // Pour consommer le '\n' restant dans le buffer

        switch (choix) {
            case 1:
                ajouter_reservation(chambres, nb_chambres, reservations, &nb_reservations);
                break;
            case 2:
                annuler_reservation(reservations, &nb_reservations);
                break;
            case 3:
                afficher_reservations(reservations, nb_reservations);
                break;
            case 4:
                rechercher_reservation(reservations, nb_reservations);
                break;
            case 5:
                afficher_chambres_disponibles(chambres, nb_chambres, reservations, nb_reservations);
                break;
            case 6:
                sauvegarder_reservations(reservations, nb_reservations);
                break;
            case 0:
                printf("Au revoir !\n");
                break;
            default:
                printf("Option invalide\n");
                break;
        }
    } while (choix != 0);

    free(reservations);
    return 0;
}

4. Afficher le Menu

Affiche le menu principal du programme.

void afficher_menu() {
    printf("\n------------------MENU------------------\n");
    printf("1: Ajouter une nouvelle réservation\n");
    printf("2: Annuler une réservation\n");
    printf("3: Afficher les réservations en cours\n");
    printf("4: Rechercher une réservation par nom de client\n");
    printf("5: Afficher la liste des chambres disponibles\n");
    printf("6: Sauvegarder les réservations dans un fichier\n");
    printf("0: Quitter le programme\n");
    printf("-----------------------------------------\n");
}

5. Ajouter une Nouvelle Réservation

Ajoute une nouvelle réservation en vérifiant la disponibilité de la chambre.

void ajouter_reservation(Chambre* chambres, int nb_chambres, Reservation* reservations, int* nb_reservations) {
    char nom[MAX_NOM];
    char prenom[MAX_NOM];
    int numero_chambre;
    struct tm date_arrivee = {0};
    struct tm date_depart = {0};

    printf("Nom du client : ");
    fgets(nom, MAX_NOM, stdin);
    nom[strcspn(nom, "\n")] = 0;

    printf("Prénom du client : ");
    fgets(prenom, MAX_NOM, stdin);
    prenom[strcspn(prenom, "\n")] = 0;

    printf("Numéro de chambre souhaité : ");
    scanf("%d", &numero_chambre);
    getchar(); // Consommer le '\n'

    printf("Date d'arrivée (JJ MM AAAA) : ");
    scanf("%d %d %d", &date_arrivee.tm_mday, &date_arrivee.tm_mon, &date_arrivee.tm_year);
    date_arrivee.tm_mon -= 1; // struct tm utilise des mois indexés à partir de 0
    date_arrivee.tm_year -= 1900; // struct tm utilise l'année depuis 1900

    printf("Date de départ (JJ MM AAAA) : ");
    scanf("%d %d %d", &date_depart.tm_mday, &date_depart.tm_mon, &date_depart.tm_year);
    date_depart.tm_mon -= 1;
    date_depart.tm_year -= 1900;

    int chambre_disponible = 0;
    for (int i = 0; i < nb_chambres; i++) {
        if (chambres[i].numero == numero_chambre && chambres[i].reservee == 0) {
            chambre_disponible = 1;
            for (int j = 0; j < *nb_reservations; j++) {
                if (reservations[j].chambre.numero == numero_chambre) {
                    if ((mktime(&date_arrivee) < mktime(&reservations[j].client.date_depart)) &&
                        (mktime(&date_depart) > mktime(&reservations[j].client.date_arrivee))) {
                        printf("Chambre non disponible pour les dates spécifiées.\n");
                        return;
                    }
                }
            }
            chambres[i].reservee = 1;
            reservations[*nb_reservations].chambre = chambres[i];
            strcpy(reservations[*nb_reservations].client.nom, nom);
            strcpy(reservations[*nb_reservations].client.prenom, prenom);
            reservations[*nb_reservations].client.date_arrivee = date_arrivee;
            reservations[*nb_reservations].client.date_depart = date_depart;
            (*nb_reservations)++;
            printf("Réservation ajoutée avec succès.\n");
            return;
        }
    }

    if (!chambre_disponible) {
        printf("Numéro de chambre invalide ou chambre déjà réservée.\n");
    }
}

6. Annuler une Réservation

Annule une réservation en fonction du nom du client.

void annuler_reservation(Reservation* reservations, int* nb_reservations) {
    char nom[MAX_NOM];
    char prenom[MAX_NOM];
    
    printf("Nom du client : ");
    fgets(nom, MAX_NOM, stdin);
    nom[strcspn(nom, "\n")] = 0;

    printf("Prénom du client : ");
    fgets(prenom, MAX_NOM, stdin);
    prenom[strcspn(prenom, "\n")] = 0;

    for (int i = 0; i < *nb_reservations; i++) {
        if (strcmp(reservations[i].client.nom, nom) == 0 &&
            strcmp(reservations[i].client.prenom, prenom) == 0) {
            for (int j = 0; j < nb_chambres; j++) {
                if (chambres[j].numero == reservations[i].chambre.numero) {
                    chambres[j].reservee = 0;
                    break;
                }
            }
            for (int k = i; k < *nb_reservations - 1; k++) {
                reservations[k] = reservations[k + 1];
            }
            (*nb_reservations)--;
            printf("Réservation annulée avec succès.\n");
            return;
        }
    }

    printf("Réservation non trouvée.\n");
}

7. Afficher les Réservations en Cours

Affiche la liste des réservations en cours.

void afficher_reservations(Reservation* reservations, int nb_reservations) {
    printf("\nRéservations en cours :\n");
    for (int i = 0; i < nb_reservations; i++) {
        printf("Client : %s %s\n", reservations[i].client.nom, reservations[i].client.prenom);
        printf("Chambre : %d (%s)\n", reservations[i].chambre.numero, reservations[i].chambre.type);
        printf("Dates : %02d/%02d/%d - %02d/%02d/%d\n",
               reservations[i].client.date_arrivee.tm_mday,
               reservations[i].client.date_arrivee.tm_mon + 1,
               reservations[i].client.date_arrivee.tm_year + 1900,
               reservations[i].client.date_depart.tm_mday,
               reservations[i].client.date_depart.tm_mon + 1,
               reservations[i].client.date_depart.tm_year + 1900);
        printf("\n");
    }
}

8. Rechercher une Réservation par Nom de Client

Rechercher une réservation par le nom du client.

void rechercher_reservation(Reservation* reservations, int nb_reservations) {
    char nom[MAX_NOM];
    char prenom[MAX_NOM];
    
    printf("Nom du client : ");
    fgets(nom, MAX_NOM, stdin);
    nom[strcspn(nom, "\n")] = 0;

    printf("Prénom du client : ");
    fgets(prenom, MAX_NOM, stdin);
    prenom[strcspn(prenom, "\n")] = 0;

    for (int i = 0; i < nb_reservations; i++) {
        if (strcmp(reservations[i].client.nom, nom) == 0 &&
            strcmp(reservations[i].client.prenom, prenom) == 0) {
            printf("Réservation trouvée :\n");
            printf("Chambre : %d (%s)\n", reservations[i].chambre.numero, reservations[i].chambre.type);
            printf("Dates : %02d/%02d/%d - %02d/%02d/%d\n",
                   reservations[i].client.date_arrivee.tm_mday,
                   reservations[i].client.date_arrivee.tm_mon + 1,
                   reservations[i].client.date_arrivee.tm_year + 1900,
                   reservations[i].client.date_depart.tm_mday,
                   reservations[i].client.date_depart.tm_mon + 1,
                   reservations[i].client.date_depart.tm_year + 1900);
            return;
        }
    }

    printf("Réservation non trouvée.\n");
}

9. Afficher la Liste des Chambres Disponibles

Affiche les chambres disponibles pour une période donnée.

void afficher_chambres_disponibles(Chambre* chambres, int nb_chambres, Reservation* reservations, int nb_reservations) {
    struct tm date_debut = {0};
    struct tm date_fin = {0};

    printf("Date de début (JJ MM AAAA) : ");
    scanf("%d %d %d", &date_debut.tm_mday, &date_debut.tm_mon, &date_debut.tm_year);
    date_debut.tm_mon -= 1;
    date_debut.tm_year -= 1900;

    printf("Date de fin (JJ MM AAAA) : ");
    scanf("%d %d %d", &date_fin.tm_mday, &date_fin.tm_mon, &date_fin.tm_year);
    date_fin.tm_mon -= 1;
    date_fin.tm_year -= 1900;

    printf("\nChambres disponibles :\n");
    for (int i = 0; i < nb_chambres; i++) {
        int disponible = 1;
        for (int j = 0; j < nb_reservations; j++) {
            if (chambres[i].numero == reservations[j].chambre.numero) {
                if ((mktime(&date_debut) < mktime(&reservations[j].client.date_depart)) &&
                    (mktime(&date_fin) > mktime(&reservations[j].client.date_arrivee))) {
                    disponible = 0;
                    break;
                }
            }
        }
        if (disponible && chambres[i].reservee == 0) {
            printf("Chambre : %d (%s) - Prix : %.2f par nuit\n", chambres[i].numero, chambres[i].type, chambres[i].prix_par_nuit);
        }
    }
}

10. Sauvegarder les Réservations

Sauvegarde les réservations dans un fichier binaire.

void sauvegarder_reservations(Reservation* reservations, int nb_reservations) {
    char nom_fichier[100];
    printf("Nom du fichier de sauvegarde : ");
    fgets(nom_fichier, 100, stdin);
    nom_fichier[strcspn(nom_fichier, "\n")] = 0;

    FILE* fichier = fopen(nom_fichier, "wb");
    if (fichier == NULL) {
        printf("Erreur d'ouverture du fichier\n");
        return;
    }

    fwrite(&nb_reservations, sizeof(int), 1, fichier);
    fwrite(reservations, sizeof(Reservation), nb_reservations, fichier);
    fclose(fichier);

    printf("Réservations sauvegardées avec succès.\n");
}

11. Charger les Réservations

Charge les réservations depuis un fichier binaire.

void charger_reservations(Reservation* reservations, int* nb_reservations) {
    char nom_fichier[100];
    printf("Nom du fichier de chargement : ");
    fgets(nom_fichier, 100, stdin);
    nom_fichier[strcspn(nom_fichier, "\n")] = 0;

    FILE* fichier = fopen(nom_fichier, "rb");
    if (fichier == NULL) {
        printf("Erreur d'ouverture du fichier\n");
        return;
    }

    fread(nb_reservations, sizeof(int), 1, fichier);
    fread(reservations, sizeof(Reservation), *nb_reservations, fichier);
    fclose(fichier);

    printf("Réservations chargées avec succès.\n");
}

 

Ajouter un commentaire

Veuillez vous connecter pour ajouter un commentaire.

Pas encore de commentaires.