Bonsoir !


Je suis un tout débutant en Pascal pour des cours d'info dans ma formation. J'ai d'assez bonnes bases de C/C++, un peu de java.

Donc je connais les "paradigmes" (?) de la programmation objet tout comme il faut, enfin il me semble que c'est clair dans ma tête tout ça .

Et là on me fait faire juste un cours de base sur les structures de données, donc rien de méchant à priori, pas de programmation objet.

Pourtant, malgré mon enthousiasme naïf, je me plante royalement en essayant de faire une chose assez simple : remplir une liste chainée (double) avec des éléments crées dynamiquement à l'aide d'un fichier.

je vais essayer d'être clair :

En exécutant mon code pas à pas, je réalise qu'une erreur run-time apparait lorsque j'insère un nouvel élément dans ma liste (au moment où j'appelle une fonction "insFin(liste : TListeD; element : TElem)", ou plutot pour être exacte quand cette fonction rend la main) . mais sur la console c'est "error file not open" qui s'affiche.

Je n'arrive pas à comprendre d'où vient l'erreur : du fichier, ou bien de l'utilisation de la liste ?


Voici les morceaux de code incriminés, demandez si vous avez besoin de plus d'infos. Il doit y avoir quelque chose que je n'ai pas saisi avec l'allocation dynamique :


Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
PROGRAM YVTP3;

uses
   YVPile, YVListD, YVTElem, YVFich;



CONST
   NOMFICH_ENTREE = 'resPat.txt';
   NOMFICH_SORTIE = 'resPat2.txt';

VAR
   listePat : TListeDouble;
   pilePat : TPile;
   rien : string;


BEGIN
   writeln('Programme d''inversion des patineurs');
   ChargerListe(listePat, NOMFICH_ENTREE); !ERREUR ICI!
   listeAfficher(listePat);
   creerPile(pilePat, listePat);
   ecrirePile(pilePat, NOMFICH_SORTIE);
   writeln('Fin du programme');
   readln(rien);
END.
ChargerListe est un fonction de l'unité YVFich :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure chargerListe(var listePat : TListeDouble; filename : string);
var fichier : Text;
    ligne : string;
    patineur : TPatineur;
begin
      creerListe(listePat);
      assign(fichier, filename);
      reset(fichier);
      while (not eof(fichier)) do begin
          readln(fichier, ligne);
          CreerPatineur(patineur, ligne);
          insFin(listePat, patineur); <- L'ERREUR ICI
      end;
      close(fichier);
end;
la procedure CreerListe initialise ma liste avec tous les pointeurs à nil et le compte d'éléments à zéro. AU fait, voici la déclaration de ma liste :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
UNIT YVListD;
 
INTERFACE
 
Uses YVTElem ;
 
TYPE
 
 
   TElem = TPatineur;
 
   TPNoeud = ^TNoeud;
 
   TNoeud = record
      suivant, precedent : TPNoeud;
      elem : TElem;
   end;
 
   TListeDouble = record
      debut, fin : TPNoeud;
      nbElem : integer;
      courant : TPNoeud;
   end;
 
 
 
 
{Création}
procedure CreerListe(var liste : TListeDouble);
 
 
{Modification}
procedure insDebut(var liste : TListeDouble; elem : TElem);
procedure insFin(var liste : TListeDouble; elem : TElem);
voici la procedure "CreerPatineur" (dans l'unité YVElem)

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
UNIT YVTElem;
INTERFACE
uses strings;
 
 
TYPE
 
   TPatineur = record
      prenom, nom : string;
      note : real;
   end;
 
{....}
IMPLEMENTATION
procedure creerPatineur(var pat : TPatineur; ligneFichier : string);
{ analyser la ligne de fichier et extraire le prénom, nom, et note }
var p1, p2, p3 : pChar;
chaine : pChar;
e : integer;
begin
   p1 := strNew(strPCopy(chaine, ligneFichier));
   p2 := strScan(p1, ';');
   p3 := strRScan(p1, ';');
   val(strPas(p3+1), pat.note, e);
   p1[p3-p1] := #0;
 
   pat.nom := strPas(p2+1);
   p1[p2-p1] := #0;
 
   pat.prenom := strPas(p1);
 
   write('Patineur crée : ' + pat.prenom + ' ' + pat.nom + ' ');
   write(pat.note);
   writeln();
 
   strDispose(p1);
end;
cette dernière fonctionne bien il me semble, l'affichage du résultat est correct.
J'ai fait ce truc qui me semble tordu car on nous a demandé d'"utiliser le type pChar" (je ne comprends pas trop car le type string pascal de base avait l'air d'avoir des fonctions pour ça... mais bref passons, il m'affiche un résultat correct)


et voici la procedure "InsFin" (de l'unité YVListD) où il y a l'erreur en question :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
procedure insFin(var liste : TListeDouble; elem : TElem);
var p : ^TNoeud;
begin
   {créer un nouveau noeud et le mettre au bon endroit}
   new(p);
   p^.precedent := liste.fin;
   p^.suivant := nil;
 
   {ici au départ j'avais mis p^.elem := elem;
   j'ai finalement essayé de mettre tout le détail, mais j'ai toujours l'erreur}
   p^.elem.prenom := elem.prenom;
   p^.elem.nom := elem.nom;
   p^.elem.note := elem.note;
 
   liste.fin := p;
 
   liste.nbElem := liste.nbElem + 1;
 
end;



L'erreur se produit au moment exact de la sortie de cette procedure ! (lorsque je fais pas à pas) . Donc j'imagine que c'est un souci avec mon pointeur... mais je n'y comprends rien.

Le fichier qu'il essaye de lire :

ResPat.txt :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
Jean;Ballin;3.5
Marc;Artan;4.5
Gilles;Deschamps;3.8
Marte;Gillot;4.7
Arnaud;Clement;5.5
Juliette;Carnot;5.9
Mireille;Ony;3.2
Marie;Gontro;4.9
Eric;Durant;5.3
Annie;Tautoo;5.5

Voici les sorties et messages d'erreur que j'obtiens:

lorsque je débug pas à pas ou lorsque je lance le programme d'un trait depuis FreePascal :

(au moment de la sortie de la procedure insFin() )
pop-up :Warning
Run Time Error 4221795
Error address $00414F04
voici le stack :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
 00406EB0 SYSTEM_HANDLEERRORADDRFRAME$LONGINT$POINTER$POINTER ()
 00406F6D SYSTEM_HANDLEERRORFRAME$LONGINT$POINTER ()
 004143C4 U_SYSTEM_OUTPUT ()
 00415B74 U_SYSINITPAS_ENTRYINFORMATION ()
 00414F04 U_SYSTEM_ENTRYINFORMATION ()
 00406B63 fpc_iocheck ()
 yvfich.pas(25) CHARGERLISTE (LISTEPAT={DEBUT = $0, FIN = $0, NBELEM = 0, COU
 yvtp3.pas(20) main ()
puis program exited with code 217

Voici l'affichage de la console :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
Programme d'inversion des patineurs
Patineur crée : Jean Ballin  3.50000000000000E+000
An unhandled exception occurred at $0040BC40 :
EInOutError : File not open
  $0040BC40
  $00401506



A l'aide! (et merci d'avance )