1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
| #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TAILLE_LOGIN 20 // nombre de caractères max pour les identifiants d'un utilisateur
#define NOMBRE_UTILISATEURS 10 // nombres max d'utilisateurs enregistrés dans le fichier utilisateurs.txt
/* -tc- ATTENTION: le nombre de caracteres max pour les identifiants d'un
utilisateur est (TAILLE_LOGIN - 1) */
typedef struct utilisateur
{
char nom[TAILLE_LOGIN];
char mdp[TAILLE_LOGIN];
} UTILISATEUR;
void effacer_utilisateur(UTILISATEUR *utilisateur); // (ré)initialise un utilisateur aux valeurs nulles
/* -tc- Indiquer la taille du tableau dans le paramètre utilisateurs ne sert a
rien d'autre qu'a documenter le code. Tu ne pourras en aucun cas
t'appuyer dessus cette information a l'interieur de la fonction */
void effacer_tableau_utilisateurs(UTILISATEUR utilisateurs[NOMBRE_UTILISATEURS]); // efface tous les utilisateurs d'un tableau et initialise un compte admin sur la première case
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
typedef struct utilisateurs
{
UTILISATEUR t_utilisateurs[NOMBRE_UTILISATEURS];
int n_utilisateurs;
} UTILISATEURS;
void effacer_utilisateurs(UTILISATEURS *utilisateurs); // supprimme tous les comptes utilisateurs et réinitialise le compte admin
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
typedef struct data // les structures DATA contiennent tout ce qui est chargé dans le main et passé en paramètre au menu.
{
UTILISATEURS utilisateurs;
} DATA;
// UTILISATEUR :
void effacer_utilisateur(UTILISATEUR *utilisateur)
{
utilisateur->nom[0] = '\0';
utilisateur->mdp[0] = '\0';
}
void effacer_tableau_utilisateurs(UTILISATEUR utilisateurs[NOMBRE_UTILISATEURS])
{
int i = 1;
/* -tc- Pourquoi utiliser un switch-case pour ecrire "ADMIN dans les champs
nom et mdp de l'utilisateur n°0 ? */
utilisateurs[0].nom[0] = '\0';
strncat(utilisateurs[0].nom, "ADMIN", TAILLE_LOGIN - 1);
utilisateurs[0].mdp[0] = '\0';
strncat(utilisateurs[0].mdp, "ADMIN", TAILLE_LOGIN - 1);
for(i = 1; i < NOMBRE_UTILISATEURS; i++)
{
effacer_utilisateur(utilisateurs + i);
}
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// UTILISATEURS :
void effacer_utilisateurs(UTILISATEURS *utilisateurs)
{
effacer_tableau_utilisateurs(utilisateurs->t_utilisateurs);
utilisateurs->n_utilisateurs = 1;
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
int effacer_fichier_utilisateurs(void)
{
UTILISATEURS utilisateurs;
FILE *fic = fopen("utilisateurs.txt", "wb");
effacer_utilisateurs(&utilisateurs);
if(fic == NULL)
{
printf("ERREUR CRITIQUE : IMPOSSIBLE DE CREER utilisateurs.txt\n");
/* -tc- ATTENTION: passer la valeur NULL a fclose() est un comportement
indetermine. Si l'ouverture du fichier a echoue, inutile de vouloir
le fermer explicitement.
fclose(fic);
*/
/* -tc- personnellement, je fais comme main(), je retourne 0 lorsque
tout va bien */
return 0;
}
else
{
/* -tc pas terrible d'ecrire et de lire un structure telle quelle avec
fwrite/fread, mais bon... */
/* -tc- a quoi ca sert de te positionner explicitement au debut du
fichier? A moins d'ouvrir le fichier en mode "a", c'est le cas par
defaut.
*/
fseek(fic, 0, SEEK_SET);
/* -tc- ATTENTION: la variable utilisateurs n'est accessible que depuis
la fonction effacer_fichier_utilisateurs(). Je ne comprends
d'ailleurs pas trop ce qu'elle fait, car elle sauve dans le fichier
une structure de donnees qui n'est pas initialisee (contenu aleatoire).
Il serait a mon sens preferable d'initialiser utilisateurs a une
valeur vide, mais connue et testable.
*/
fwrite(&utilisateurs, sizeof(UTILISATEURS), 1, fic);
}
fclose(fic), fic = NULL;
return 1;
}
int charger_fichier_utilisateurs(UTILISATEURS *utilisateurs)
{
FILE *fic = fopen("utilisateurs.txt", "r+b");
if(fic == NULL)
{
printf("ERREUR : FICHIER utilisateurs.txt MANQUANT, LANCEZ LA FONCTION effacer_utilisateurs\n");
/* -tc- ATTENTION: passer la valeur NULL a fclose() est un comportement
indetermine. Si l'ouverture du fichier a echoue, inutile de vouloir
le fermer explicitement.
fclose(fic);
*/
return 0;
}
else
{
/* -tc- inutile */
fseek(fic, 0, SEEK_SET);
/* -tc- utilisateurs est deja un pointeur sur une structure de type
UTILSATEURS. Pas besoin de l'operateur d'adressage ici.
*/
fread(utilisateurs, sizeof(UTILISATEURS), 1, fic);
fclose(fic), fic = NULL;
return 1;
}
}
int charger_data(DATA *data)
{
printf("DEBUG : charger_dataD");
/* -tc- charger_fichier_utilisateurs() retourne 0 en cas d'echec */
if(0 == charger_fichier_utilisateurs(&(data->utilisateurs)))
{
effacer_fichier_utilisateurs(); // Si le fichier utilisateurs.txt manque on le crée, puis on relance charger_fichier_carte
if(0 == charger_fichier_utilisateurs(&(data->utilisateurs)))
{
printf("ERREUR CRITIQUE : impossible de creer le fichier utilisateurs.txt. Arret du programme.\n");
return 0;
}
}
printf("DEBUG : charger_dataF");
return 1;
}
int main(void)
{
DATA data;
if (0 == charger_data(&data))
{
return EXIT_FAILURE;
}
printf("DEBUG : CHKPT");
return 0;
} |
Partager