Exercice — types, instructions et primitives de fichiers (6 points), dans l'esprit des sessions 2016–2026
Soient le tableau de déclaration des nouveaux types et le tableau de déclaration des objets suivants :
| Nouveaux types |
|---|
| Produit = Enregistrement Ref : Chaîne Qte : Octet Prix : Réel Dispo : Booléen Fin |
| FProduits = Fichier de Produit |
| FReels = Fichier de Réel |
| TabP = Tableau de 100 Produit |
| Objet | Type / Nature |
|---|---|
| F | Fichier texte |
| P | Produit |
| T | TabP |
| Fp | FProduits |
| Fr | FReels |
| n | Octet |
| ok | Booléen |
On considère les instructions du tableau suivant :
| Instruction | V/F | Justification |
|---|---|---|
n ← Fin_fichier (Fp) | ||
Ecrire (Fr, P.Prix) | ||
Ecrire (Fp, P.Ref) | ||
ok ← P.Qte > 0 | ||
T[3] ← P | ||
T[3] ← P.Prix | ||
Lire (Fr, n) | ||
P.Qte ← 300 |
Le fichier d'enregistrements "Stock.dat", de type FProduits, est déjà rempli. On veut écrire, dans le fichier texte "Rupture.txt", la référence de chaque produit dont la quantité est nulle, à raison d'une référence par ligne. On donne ci-après l'algorithme d'une fonction Ruptures censée réaliser ce traitement et retourner le nombre de produits en rupture. Cependant, cinq lignes de cet algorithme comportent des erreurs dans l'emploi des primitives de fichiers ou dans les types.
Fonction Ruptures (ch1, ch2 : Chaîne) : Entier
DEBUT
Ouvrir (ch1, Fp, "wb")
Ouvrir (ch2, F, "w")
nb ← 0
Tant que Non (Fin_fichier (Fp)) Faire
Lire_ligne (Fp, P)
Si P.Qte = "0" Alors
Ecrire_nl (F, P)
nb ← nb + 1
Fin Si
Fin Tant que
Fermer (Fp)
Fermer (F)
Retourner nb > 0
FINNB : ch1 et ch2 contiennent les chemins d'accès et les noms physiques des fichiers "Stock.dat" et "Rupture.txt".
Travail demandé :
- Reproduire le tableau des instructions et valider chacune d'elles en mettant la lettre V si l'instruction est valide ou la lettre F dans le cas contraire. Justifier la réponse si l'instruction est invalide.
- Questions sur la fonction Ruptures.
- Reproduire le tableau ci-dessous et y inscrire, pour chaque ligne erronée, la ligne telle qu'elle apparaît dans l'algorithme, puis sa correction.
- Dresser le tableau de déclaration des objets locaux de la fonction Ruptures corrigée.
- Un élève propose de remplacer la ligne
Tant que Non (Fin_fichier (Fp)) FaireparPour i de 1 à Fin_fichier (Fp) Faire.- Expliquer pourquoi cette proposition est invalide.
- Écrire l'algorithme d'une fonction Existe(ch1, r) qui retourne Vrai si la référence r figure dans "Stock.dat", en utilisant la structure itérative adéquate pour arrêter la lecture dès que la référence est trouvée.
- "Stock.dat" contient, dans cet ordre, les produits ("R-101" ; 12 ; 4.5 ; Vrai), ("R-207" ; 0 ; 12.75 ; Faux), ("R-315" ; 3 ; 7.2 ; Vrai) et ("R-422" ; 0 ; 30 ; Faux). Donner le contenu de "Rupture.txt" et la valeur retournée par la fonction Ruptures corrigée, puis le nombre d'enregistrements lus par l'appel Existe(ch1, "R-315").
| Ligne erronée | Correction |
|---|---|
Voir la correction commentéeAprès avoir posé votre démarche
1. Idée : pour chaque instruction, comparer le type de ce qui est produit (valeur retournée, champ, enregistrement) au type de ce qui le reçoit (variable, case, fichier typé), sans oublier le domaine de valeurs d'un Octet.
| Instruction | V/F | Justification |
|---|---|---|
n ← Fin_fichier (Fp) | F | Fin_fichier retourne un booléen, alors que n est de type Octet. |
Ecrire (Fr, P.Prix) | V | |
Ecrire (Fp, P.Ref) | F | Fp est un fichier d'enregistrements de type Produit ; P.Ref est un champ de type Chaîne. |
ok ← P.Qte > 0 | V | |
T[3] ← P | V | |
T[3] ← P.Prix | F | T[3] est un enregistrement de type Produit ; P.Prix est un réel. |
Lire (Fr, n) | F | Fr est un fichier de réels : la valeur lue est un réel, et n est de type Octet. |
P.Qte ← 300 | F | Le champ Qte est de type Octet, dont les valeurs vont de 0 à 255. |
Ecrire (Fr, P.Prix) est valide : un fichier de réels reçoit un réel. ok ← P.Qte > 0 affecte à un booléen le résultat d'une comparaison. T[3] ← P copie un enregistrement entier dans une case de même type.
2.a Idée : relire l'algorithme ligne par ligne en se demandant : le mode convient-il à l'usage du fichier ? la primitive convient-elle à la nature du fichier ? le type de la valeur convient-il à ce qui la reçoit ?
| Ligne erronée | Correction |
|---|---|
Ouvrir (ch1, Fp, "wb") | Ouvrir (ch1, Fp, "rb") |
Lire_ligne (Fp, P) | Lire (Fp, P) |
Si P.Qte = "0" Alors | Si P.Qte = 0 Alors |
Ecrire_nl (F, P) | Ecrire_nl (F, P.Ref) |
Retourner nb > 0 | Retourner nb |
"Stock.dat" est déjà rempli : le mode "wb" le recrée vide, il faut le lire en "rb". Lire_ligne ne s'applique qu'à un fichier texte ; un fichier d'enregistrements se lit enregistrement par enregistrement avec Lire. Qte est un Octet, comparé à l'entier 0 et non à la chaîne "0". "Rupture.txt" est un fichier texte : on y écrit la chaîne P.Ref, pas l'enregistrement. Enfin, la fonction est de type Entier : elle retourne nb, et non le booléen nb > 0.
2.b
| Objet | Type / Nature | Rôle |
|---|---|---|
| Fp | FProduits | Fichier "Stock.dat" |
| F | Fichier texte | Fichier "Rupture.txt" |
| P | Produit | Enregistrement lu |
| nb | Entier | Nombre de produits en rupture |
3.a Fin_fichier(Fp) retourne un booléen (Vrai lorsque la fin est atteinte), et non le nombre d'enregistrements : il ne peut pas servir de borne à une boucle Pour. De plus, le nombre d'enregistrements d'un fichier n'est pas connu d'avance ; on le parcourt donc avec une boucle à condition d'arrêt.
3.b Idée : deux raisons de s'arrêter, la fin du fichier ou la référence trouvée ; on les réunit dans la condition d'un Tant que.
Fonction Existe (ch1, r : Chaîne) : Booléen
DEBUT
Ouvrir (ch1, Fp, "rb")
trouve ← Faux
Tant que Non (trouve) Et Non (Fin_fichier (Fp)) Faire
Lire (Fp, P)
trouve ← (P.Ref = r)
Fin Tant que
Fermer (Fp)
Retourner trouve
FIN| Objet | Type / Nature | Rôle |
|---|---|---|
| Fp | FProduits | Fichier "Stock.dat" |
| P | Produit | Enregistrement lu |
| trouve | Booléen | Vrai dès que la référence r est lue |
4. Seuls "R-207" et "R-422" ont une quantité nulle. "Rupture.txt" contient les deux lignes :
R-207
R-422La fonction Ruptures retourne . L'appel Existe(ch1, "R-315") lit 3 enregistrements : la boucle s'arrête dès la lecture de "R-315", sans lire "R-422".