Mise à jour d’un fichier LINE SEQUENTIAL sous OpenCobolIDE
Dans beaucoup de cours, on voit la combinaison OPEN I-O, REWRITE et DELETE pour modifier ou supprimer un enregistrement.
Le problème est que, sous OpenCobolIDE (et donc GnuCOBOL), cette approche n’est pas autorisée quand le fichier est déclaré en
ORGANIZATION IS LINE SEQUENTIAL.
Un fichier
LINE SEQUENTIAL est un fichier texte “ligne par ligne”.
Comme les lignes peuvent être écrites avec des longueurs physiques variables (fin de ligne, traitements des espaces, etc.),
le compilateur refuse la mise à jour “sur place”. Résultat : erreurs de compilation du type
OPEN I-O not allowed et DELETE not allowed.
Objectif du cours
L’objectif reste le même : parcourir un fichier de notes, proposer une action sur chaque ligne (modifier, supprimer, conserver),
puis obtenir un fichier final mis à jour.
La différence est la méthode : pour un fichier texte LINE SEQUENTIAL, on fait une mise à jour par recopie.
Ce que vous aviez tenté (et pourquoi ce n’est pas adapté)
Le code ci-dessous ressemble à une approche “mise à jour directe”.
Sous OpenCobolIDE, il déclenche les erreurs mentionnées, car il mélange
LINE SEQUENTIAL avec OPEN I-O et DELETE.
IDENTIFICATION DIVISION.
PROGRAM-ID. MISE-A-JOUR-FICHIER.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FICHIER-NOTES ASSIGN TO "notes.txt"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD FICHIER-NOTES.
01 ENREGISTREMENT-NOTE.
05 NUMERO-ETUDIANT PIC 9(5).
05 NOM PIC X(20).
05 NOTE PIC 9(2)V9.
WORKING-STORAGE SECTION.
01 FIN-FICHIER PIC X VALUE "N".
01 CHOIX PIC X.
01 NOUVELLE-NOTE PIC 9(2)V9.
PROCEDURE DIVISION.
OPEN I-O FICHIER-NOTES.
PERFORM TRAITER-ENREGISTREMENT UNTIL FIN-FICHIER = "O".
CLOSE FICHIER-NOTES.
DISPLAY "Mise à jour terminée.".
STOP RUN.
TRAITER-ENREGISTREMENT.
READ FICHIER-NOTES
AT END
MOVE "O" TO FIN-FICHIER
NOT AT END
DISPLAY "Action ? ..."
ACCEPT CHOIX
EVALUATE TRUE
WHEN CHOIX = "M"
ACCEPT NOUVELLE-NOTE
MOVE NOUVELLE-NOTE TO NOTE
REWRITE ENREGISTREMENT-NOTE
WHEN CHOIX = "S"
DELETE FICHIER-NOTES
END-EVALUATE
END-READ.
La méthode compatible : recopie dans un fichier temporaire
La mise à jour d’un fichier texte se fait en 5 étapes très simples :
- Ouvrir le fichier d’origine en
INPUT(lecture). - Ouvrir un fichier temporaire en
OUTPUT(écriture). - Lire chaque enregistrement avec
READ. - Selon le choix utilisateur : écrire une version modifiée, recopier telle quelle, ou ne rien écrire (suppression logique).
- À la fin, remplacer
notes.txtparnotes.tmp.
Cette technique marche partout pour les fichiers texte. Elle reflète aussi une réalité terrain : de nombreux traitements “batch” historiques mettent à jour des fichiers séquentiels par reconstruction.
Code corrigé (compatible OpenCobolIDE)
Dans cet exemple, la note est stockée en texte PIC X(4) pour être cohérente avec un fichier lisible comme 12.5, 08.0.
Si vous voulez un format purement numérique (implied decimal), il faut alors stocker les notes sans point (ex. 125 pour 12,5), ce qui rend le fichier moins lisible.
IDENTIFICATION DIVISION.
PROGRAM-ID. MISE-A-JOUR-FICHIER-TEXTE.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT FICHIER-IN ASSIGN TO "notes.txt"
ORGANIZATION IS LINE SEQUENTIAL.
SELECT FICHIER-OUT ASSIGN TO "notes.tmp"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD FICHIER-IN.
01 ENREG-IN.
05 NUMERO-ETUDIANT-IN PIC 9(5).
05 NOM-IN PIC X(20).
05 NOTE-IN PIC X(4).
FD FICHIER-OUT.
01 ENREG-OUT.
05 NUMERO-ETUDIANT-OUT PIC 9(5).
05 NOM-OUT PIC X(20).
05 NOTE-OUT PIC X(4).
WORKING-STORAGE SECTION.
01 FIN-FICHIER PIC X VALUE "N".
01 CHOIX PIC X VALUE SPACE.
01 NOUVELLE-NOTE PIC X(4) VALUE SPACES.
PROCEDURE DIVISION.
OPEN INPUT FICHIER-IN
OPEN OUTPUT FICHIER-OUT
PERFORM UNTIL FIN-FICHIER = "O"
READ FICHIER-IN
AT END
MOVE "O" TO FIN-FICHIER
NOT AT END
DISPLAY SPACE
DISPLAY "Étudiant : " NUMERO-ETUDIANT-IN " " NOM-IN " - Note : " NOTE-IN
DISPLAY "Action ? (M=modifier, S=supprimer, Entrée=passer) : "
ACCEPT CHOIX
EVALUATE TRUE
WHEN CHOIX = "M" OR CHOIX = "m"
DISPLAY "Nouvelle note (ex: 16.0) : "
ACCEPT NOUVELLE-NOTE
MOVE NUMERO-ETUDIANT-IN TO NUMERO-ETUDIANT-OUT
MOVE NOM-IN TO NOM-OUT
MOVE NOUVELLE-NOTE TO NOTE-OUT
WRITE ENREG-OUT
DISPLAY "Note modifiée (écrite dans notes.tmp)."
WHEN CHOIX = "S" OR CHOIX = "s"
DISPLAY "Enregistrement supprimé (non recopié)."
WHEN OTHER
MOVE NUMERO-ETUDIANT-IN TO NUMERO-ETUDIANT-OUT
MOVE NOM-IN TO NOM-OUT
MOVE NOTE-IN TO NOTE-OUT
WRITE ENREG-OUT
DISPLAY "Enregistrement conservé (recopié)."
END-EVALUATE
END-READ
END-PERFORM
CLOSE FICHIER-IN
CLOSE FICHIER-OUT
DISPLAY "Traitement terminé."
DISPLAY "Renommez notes.tmp en notes.txt (ou remplacez notes.txt par notes.tmp)."
STOP RUN.
Copier le code
Exemple de fichier notes.txt avant exécution
Chaque ligne correspond à un enregistrement de longueur fixe :
9(5) pour le numéro (5 chiffres),
X(20) pour le nom (rempli avec des espaces),
et X(4) pour la note (ex. 08.0).
00001DUPONT Jean 12.5
00002MARTIN Sophie 08.0
00003BERNARD Lucas 15.5
00004DURAND Emma 09.0
Exemple de résultat (fichier temporaire notes.tmp)
Si vous modifiez l’étudiant 00001 en 16.0
et si vous “supprimez” 00002 (donc vous ne le recopiez pas), le fichier temporaire contiendra :
00001DUPONT Jean 16.0
00003BERNARD Lucas 15.5
00004DURAND Emma 09.0
Explications détaillées
1) Deux fichiers au lieu d’un seul
-
FICHIER-IN: lecture du fichier d’origine (notes.txt) en modeINPUT. -
FICHIER-OUT: création d’un nouveau fichier (notes.tmp) en modeOUTPUT.
2) Modifier une ligne
Quand l’utilisateur choisit M, on lit la nouvelle note, puis on écrit dans le fichier temporaire une ligne identique,
sauf la note remplacée.
Ici, on utilise WRITE, jamais REWRITE.
3) Supprimer une ligne
Pour “supprimer” un enregistrement dans un fichier texte, on ne peut pas retirer une ligne au milieu du fichier.
La suppression se fait donc par une règle simple : ne pas écrire la ligne dans le fichier temporaire.
Il n’y a donc pas de DELETE dans cet exemple.
4) Conserver une ligne
Si l’utilisateur ne fait rien (Entrée) ou choisit une autre touche, on recopie la ligne telle quelle dans le fichier temporaire.
Si vous souhaitez enseigner
OPEN I-O, REWRITE et DELETE,
faites-le dans un chapitre “fichiers indexés” (ORGANIZATION IS INDEXED) ou “fichiers relatifs”.
Sur LINE SEQUENTIAL, la méthode fiable est la recopie.
Résumé à retenir
- Un fichier
LINE SEQUENTIALest un fichier texte : mise à jour directe refusée dans OpenCobolIDE. - Pour modifier/supprimer : lire
notes.txtet écrire un nouveaunotes.tmp. - “Supprimer” = ne pas recopier la ligne.
- “Modifier” = recopier avec une valeur modifiée.
- En fin de traitement : remplacer
notes.txtparnotes.tmp.