Dans cet exercice, nous gérons des fichiers de notes.
Vous pouvez trouver une liste d'étudiants
à
cette adresse.
L'exercice se compose de deux parties.
Dans une première partie, vous générez un fichier de notes à partir
de la liste d'étudiants.
Dans la seconde partie, vous apprenez à modifier ce fichier de notes.
Création du fichier de note
Dans cette partie, nous écrivons un programme nommé
generate. Ce programme
doit recevoir trois arguments :
- un fichier d'entrée contenant des noms d'étudiants (le fichier
student.txt),
- un fichier de sortie contenant des noms d'étudiants et des notes,
- une note initiale.
Le programme
generate doit affecter la note initiale à chacun des étudiants
du fichier d'entrée, et écrire le résultat dans le fichier de sortie.
Pour commencer, vérifiez que votre programme reçoit bien trois arguments.
Si ce n'est pas le cas, votre programme doit se terminer avec un message d'erreur adéquat.
Ensuite, votre programme doit ouvrir les fichiers d'entrée et de sortie, respectivement
en lecture seul, et en écriture tronquée (i.e., si le fichier existe, il est tronqué).
Si vous rencontrez une erreur pendant l'une des ouvertures, vous veillerez
à quitter votre programme avec un message d'erreur adéquat. Pour cela,
pensez à utiliser strerror(errno).
Maintenant, votre programme doit lire le fichier d'entrée ligne à ligne, jusqu'à la fin
du fichier, en utilisant la fonction fgets.
Dans un premier temps, votre programme doit simplement afficher le nom de chaque étudiant dans le terminal.
On considère qu'un nom est correct si il fait moins de 256 caractères.
Dans le code, au lieu d'utiliser directement la valeur 256, on vous demande de définir
cette valeur à l'aide d'une macro, et de placer cette macro dans un fichier
d'entête nommé student.h, que vous devez inclure avec la directive #include.
Ajoutez au fichier
student.h la définition d'une structure nommée
student et contenant les champs suivants :
-
name: le nom de l'étudiant. Ce nom est une chaîne faisant au plus 256 caractères.
Pensez à utiliser votre macro plutôt que d'écrire directement ce 256.
-
rank: la note associé à l'étudiant. On ne considère que des notes entières
dans l'exercice.
Dans
generate, au lieu d'afficher le nom de l'étudiant, vous devez remplir
une instance de la structure
student avec le nom de l'étudiant se trouvant
dans le fichier d'entrée et avec la note initiale passée en argument.
Après avoir rempli cette structure, écrivez là dans le fichier de sortie avec la fonction
fwrite.
Comme vous êtes une promotion exceptionnelle, vous pouvez naturellement affecter la note initiale
de 17 à tous les étudiants ! Bravo à toutes et à tous !
Modification du fichier de notes
Dans cette partie, nous écrivons un nouveau programme nommé
modify, prenant
trois arguments :
- un fichier de notes,
- un nom d'étudiant,
- une note.
Vous remarquerez qu'un nom d'étudiant est composé d'un ou plusieurs prénoms et d'un ou plusieurs noms,
le tout séparé par des espaces.
Comme l'espace sur la ligne de commande est le séparateur d'argument, appeler
modify notes.dat Zabeth La Chouette 20 revient à appeler le programme
modify avec 5 arguments et non 3.
Comme vous vous souvenez parfaitement, et avec nostalgie, du module CSC3102, vous n'avez, bien entendu, pas
oublié qu'une chaîne de caractère entourée de guillemets compte comme un unique argument.
En d'autres termes,
modify notes.dat "Zabeth La Chouette" 20 appelle
bien le programme
modify avec trois arguments.
Pour commencer, vérifiez que le nombre d'arguments est correct et que, lors de l'ouverture
du fichier de notes passé en argument en mode lecture-écriture, vous n'avez pas d'erreur.
Pensez à utiliser strerror(errno) pour afficher de façon conviviale
l'éventuelle erreur d'ouverture.
Plutôt que de lire les notes d'étudiants une par une, nous souhaitons lire l'ensemble
des notes avec un unique appel à fread. Pour cela, il faut être capable
de connaître la taille de votre fichier.
En utilisant judicieusement fseek et ftell, essayez de trouver
la taille du fichier en nombre d'octets.
Affichez cette taille, et vérifiez que cette taille est correcte en la comparant
à ce que vous donne la commande ls -l.
Maintenant que nous connaissons la taille du fichier, nous pouvons en déduire
le nombre d'étudiants en divisant la taille du fichier par la taille d'une structure student.
Après avoir inclus le fichier student avec la directive #include,
calculez et affichez le nombre d'étudiants.
Allouez maintenant un tableau pouvant recevoir les étudiants avec la fonction malloc.
Utilisez ce tableau pour lire l'ensemble du fichier de notes avec un unique appel à
fread.
Affichez maintenant la note de chaque étudiant en parcourant votre tableau d'étudiants.
Après l'affichage de la note de chaque étudiant effectué à la question précédente,
effectuez un second parcours du tableau d'étudiant.
Pendant ce parcours, vous devez trouver l'étudiant dont le nom est passé en argument.
Une fois cet étudiant identifié :
- modifiez sa note en utilisant le dernier paramètre de modify,
- positionnez de façon adéquat la tête de lecture du fichier de notes
sur son entrée,
- écrivez les nouvelles valeurs de sa structure student.
Vous pouvez vérifier que votre modification est correcte en lançant une seconde fois modify,
puisque modify affiche aussi la note de chaque étudiant (voir question précédente).