Tableau de record et de type énumé

Tableau de record et de type énumé - Ada - Programmation

Marsh Posté le 04-12-2006 à 22:11:22    

Bonjour à tous,
 
J'ai déjà posté pour d'autres sujets en ada couronnés de succès, merci bien !
 
Cependant je découvre avec désarois un problème majeur dans mon exercice.
 
Suivant la classification des types, un type tableau peut il contenir un type énumaratif ?
 
Regardez le code suivant, les erreurs divers (type ou déclaration de variables) sont surements la source de mon soucis :
 

Code :
  1. WITH Ada.Text_IO; USE Ada.Text_IO;
  2. WITH Ada.Integer_Text_IO; USE Ada.Integer_Text_IO;
  3. WITH Ada.Float_Text_IO; USE Ada.Float_Text_IO;
  4. PROCEDURE Cpte_Banquaire IS
  5.  
  6.    SUBTYPE Id_Banque IS Integer RANGE 100..500;
  7.    SUBTYPE Num_Banque IS Integer RANGE 1..100000;
  8.    SUBTYPE Solde_Cpte IS Float;
  9.    
  10.    TYPE T_En_Tete IS
  11.       RECORD
  12.       Bk:Id_Banque;
  13.       NBk:Num_Banque;
  14.       SC:Solde_Cpte;
  15.       END RECORD;
  16.    
  17.    SUBTYPE Num_Jour IS Integer RANGE 1..31; 
  18.    SUBTYPE Num_Mois IS Integer RANGE 1..12; 
  19.    SUBTYPE Num_Annee IS Integer RANGE 1900..2100;
  20.  
  21.  
  22.    TYPE T_Date IS
  23.    RECORD
  24.       jour:Num_Jour;
  25.       mois:Num_Mois;
  26.       Annee:Num_Annee;
  27.    END RECORD;
  28.  
  29.    TYPE T_Rubrique IS (Salaire, Versement, Loisirs, Maison, Divers);
  30.    TYPE T_Mode_Paiement IS (Cb, Cheque, Virement);
  31.  
  32.        
  33.    TYPE t_Nblignes IS
  34.    RECORD
  35.       Valeur:float;
  36.       Date:t_date;
  37.       Rubrique:T_Rubrique;
  38.       Mode_Paiement:T_Mode_Paiement;
  39.    END RECORD;
  40.  
  41.    TYPE T_nblignes_Comptable IS ARRAY (1..10) OF T_Nblignes;
  42.  
  43.    PROCEDURE Ligne_Comptable IS
  44.  
  45.       nblignes:T_Nblignes;
  46.       Date: T_Date;
  47.       rubrique:T_Rubrique;
  48.       mod_p:t_mode_paiement;
  49.    nblignes_Compta:T_nblignes_Comptable;     
  50.       begin
  51.          
  52.          FOR I IN 1..2 LOOP
  53.          
  54.       Put("Rentrer une date :" );
  55.          
  56.             New_Line;
  57.             Get(nblignes.Date.jour);
  58.             nblignes_Compta(I).Date.Jour:=Date.Jour;
  59.             nblignes_Compta(I).Date.mois:=Date.mois;
  60.             nblignes_Compta(I).Date.annee:=Date.annee;
  61.            
  62.        
  63.       Put("Rentrer une Valeur :" );
  64.             New_Line;
  65.             Get(nblignes.Valeur);
  66.             nblignes_compta(i).valeur:=nblignes.valeur;
  67.             New_Line;
  68.       Put("Rentrer une Rubrique :" );
  69.             New_Line;
  70.             Get(rubrique.Rubrique);
  71.             nblignes_Compta(I).rubrique:=rubrique.rubrique;
  72.       New_Line;
  73.       Put("Rentrer un mode de paiement :" );
  74.             New_Line;
  75.             Get(mode_p.Mode_Paiement);
  76.             nblignes_Compta(I).Mode_Paiement:=mode_p.mode_paiement;
  77.             New_Line;
  78.          END LOOP;
  79.       New_line;
  80.       Put("   Date   Valeur   Rubrique   Mode  " );
  81.       New_Line;
  82.      END Ligne_Comptable;
  83.      
  84. begin
  85.    Ligne_Comptable;
  86. END Cpte_Banquaire;


 
Au départ j'avais uniquement déclaré les variables nblignes_Compta et nblignes car nblignes_Compta est un tableau de nblignes.
 
Cependant nblignes est un record avec des types énumérés et là ça coince.
 
Donc j'ai pensé appeler le type article directement, je sais c'est pas le truc le plus malin que j'ai fait.
 
L'erreur que je retrouve est "invalid prefix in selected component"test"".
J'en déduis une erreur dans la déclaration de ma variable, je pense devoir directement utiliser des types t_nblignes dans un tableau t_nblignes_compta dans mes déclarations et rien d'autre.
 
A vous de juger et d'éliminer le maillon faible...
Merci de votre aide.
 
 

Reply

Marsh Posté le 04-12-2006 à 22:11:22   

Reply

Marsh Posté le 05-12-2006 à 11:57:11    

salut stupid_coder, ... tu peut nous dire ce que fait ton programme et comment, en français s'il te plais
apres je décode ton code ... si j'y parviens.  

Reply

Marsh Posté le 05-12-2006 à 13:12:04    

bonjour Jovalise,
dès que je fais le point sur le code, avec plus de clarté, je le poste avec des commentaires et de plus amples explications ce soir.
Merci.

Reply

Marsh Posté le 05-12-2006 à 13:38:23    

Après d'eventuelles corrections ("mode_p" -> "mod_p" )
j'obtien le message suivant


gcc-3.4 -c main.adb
main.adb:73:20: invalid prefix in selected component "rubrique"
main.adb:74:45: invalid prefix in selected component "rubrique"
main.adb:78:20: invalid prefix in selected component "mod_p"
main.adb:79:50: invalid prefix in selected component "mod_p"
gnatmake: "main.adb" compilation error


je n'ai pas trouvé le component "test" dans le code.

Reply

Marsh Posté le 05-12-2006 à 14:36:01    

j'ai du faire des changements de code en cours de route...
 
je te poste le dernier code, que j'ai refais, avec l'erreur donnée qui ressemble beaucoup à ce que tu cites.

Reply

Marsh Posté le 05-12-2006 à 14:45:24    

Code :
  1. WITH Ada.Text_IO; USE Ada.Text_IO;
  2. WITH Ada.Integer_Text_IO; USE Ada.Integer_Text_IO;
  3. WITH Ada.Float_Text_IO; USE Ada.Float_Text_IO;
  4. --with ada.Characters; use ada.Characters;
  5. PROCEDURE Cpte_Banquaires IS
  6.  
  7.    SUBTYPE Id_Banque IS Integer RANGE 100..500;
  8.    SUBTYPE Num_Banque IS Integer RANGE 1..100000;
  9.    SUBTYPE Solde_Cpte IS Float;
  10.    
  11.    TYPE T_En_Tete IS
  12.       RECORD
  13.       Bk:Id_Banque;
  14.       NBk:Num_Banque;
  15.       SC:Solde_Cpte;
  16.       END RECORD;
  17.    
  18.    SUBTYPE Num_Jour IS Integer RANGE 1..31; 
  19.    SUBTYPE Num_Mois IS Integer RANGE 1..12; 
  20.    SUBTYPE Num_Annee IS Integer RANGE 1900..2100;
  21.  
  22.  
  23.    TYPE T_Date IS
  24.    RECORD
  25.       jour:Num_Jour;
  26.       mois:Num_Mois;
  27.       Annee:Num_Annee;
  28.    END RECORD;
  29.  
  30.    TYPE T_Rubrique IS (Salaire, Versement, Loisirs, Maison, Divers);
  31.    TYPE T_Mode_Paiement IS (Cb, Cheque, Virement);
  32.  
  33.        
  34.    TYPE t_Nblignes IS
  35.    RECORD
  36.       Valeur:float;
  37.       Date:t_date;
  38.       Rubrique:T_Rubrique;
  39.       Mode_Paiement:T_Mode_Paiement;
  40.    END RECORD;
  41.  
  42.    TYPE T_Nblignes_Comptable IS ARRAY (1..10) OF T_Nblignes;
  43.  
  44.    PROCEDURE Suivi_Banquaire IS
  45.      
  46.       lignes_A:T_Nblignes_Comptable;
  47.       tab_B:t_Nblignes;
  48.      
  49.    BEGIN
  50.       FOR I IN 1..1 LOOP
  51.                    
  52.          Put("Veuillez saisir le jour du retrait :" );
  53.          New_Line;
  54.          Get(tab_B.date.Jour);
  55.          lignes_A(I).date.Jour:=tab_B.date.Jour;
  56.          Get(tab_B.Date.Mois);
  57.          lignes_A(I).Date.Mois:=tab_B.Date.Mois;
  58.          Get(tab_B.Date.Annee);
  59.          lignes_A(I).Date.Annee:=tab_B.Date.Annee;
  60.        
  61.          Put("Veuillez saisir une valeur :" );
  62.          New_Line;
  63.          Get(tab_b.Valeur);
  64.          lignes_A(I).Valeur:=tab_b.Valeur;
  65.        
  66.          Put("Veuillez saisir une rubrique :" );
  67.          New_Line;
  68. /*l'erreur est sur le "get" -problème "invalid parameter list in call"- si tu mets en commentaire les 2 lignes
  69. en dessous alors le code est compilé.*/
  70.          Get(tab_B.Rubrique);
  71.          lignes_a(i).rubrique:=tab_B.Rubrique;
  72.          END LOOP;
  73.       New_Line;
  74.      
  75.       Put("  date       valeur   rubrique   mode   " );
  76.       FOR I IN 1..1 LOOP
  77.          new_line;
  78.          Set_Col(1);
  79.          Put(lignes_A(I).Date.Jour,0);
  80.          PUT("/" );
  81.          Put(lignes_A(I).Date.Mois,0);
  82.          PUT("/" );
  83.          Put(lignes_A(I).Date.Annee,0);
  84.             SET_Col(15);
  85.          Put(lignes_A(I).Valeur,2,0,0);
  86.             Set_Col(20);
  87. --            put(a(i).rubrique);
  88.        
  89.       end loop;
  90.      
  91.       END Suivi_Banquaire;
  92. BEGIN
  93.    Suivi_Banquaire;
  94. END Cpte_Banquaires;


 
 

Reply

Marsh Posté le 05-12-2006 à 17:15:06    

Pour ta question "Suivant la classification des types, un type tableau peut il contenir un type énumaratif ?", la classification des types et la possibilité de construire des tableaux d'lement de type enumératif n'on pas de relation. Mais oui, on peut construire des tableaux d'élément de type énumératif.
 
Pour le problème de la ligne 73, tu as au moins 3 solutions.
la premiere c'est de reecrire la fonction get pour le type T_Rubrique comme tu veux.
la deuxieme c'est de saisir un entier correspondant à la position de la valeur du type.
la troisiemme, c'est de saisir une chaine de caractere representant le non de la veur du type, du faire un uper_case et de comparer cette chaine avec le non de la valeur du type T_Rubrique.
Si je ne me suis pas bien exprimé, d'abord, désolé, puis, je peut te montrer un exemple.

Reply

Marsh Posté le 05-12-2006 à 17:39:24    

Code :
  1. ......
  2. ......
  3. --En declarant ::=
  4. longeur_max_nom_valeur_type_T_Rubrique : constante integer := 10;
  5. Rubrique : string (1..longeur_max_noms_valeurs_type_T_Rubrique) := (others => ascii.nul);
  6. last_char : natural := 0;
  7. .....
  8. .....
  9. -- Puis en faisant les appels suivant ::=
  10. get_line(Rubrique,last_char);
  11. Tab_B.Rubrique := T_Rubrique'value(to_uper(Rubrique(1..last_char)));
  12. ......
  13. ......


Par exemple de la solution 2

Reply

Marsh Posté le 05-12-2006 à 17:41:43    

Jovalise,
 
Si je comprends bien, l'utilisation du type t_rUbrique n'est pas exploitable dans l'état actuel...
 
Actuellement le get ne prend en compte que les integer, float ou string en gros ?
Donc créer une fonction get qui prenne les types énumératif.

Reply

Marsh Posté le 05-12-2006 à 17:54:15    

Et bien, si je ne me trompe pas, oui, je ne connais pas de librairie qui propose une fonction get pour le type T_Rubrique. Soit, on te la fournit, soit tu l'implémente. ... Il me semble que c'est ça.

Reply

Marsh Posté le 05-12-2006 à 17:54:15   

Reply

Marsh Posté le 05-12-2006 à 18:01:48    

Mais comme tu peux le voir, l'attribut Value qui s'appique à des types enumérés, renvoie la valeur qui porte le nom donné en parametre.

Reply

Marsh Posté le 05-12-2006 à 18:02:23    

tout ce qui touche au type énumération est il compris dans ada.text_io ?

Reply

Marsh Posté le 05-12-2006 à 18:04:08    

ce serait plutot dans standard.

Reply

Marsh Posté le 05-12-2006 à 18:06:40    

Mais je comprend pas trops la question en fait, je suis un amateur moi sais-tu  :jap:

Reply

Marsh Posté le 05-12-2006 à 18:07:49    

dis moi, je ne t'ai pas expliqué le rendu de ce programme; mais quand tu le compiles (en mettant en commentaire les 2 lignes incriminées), le résultat est explicite ?

Reply

Marsh Posté le 05-12-2006 à 18:15:18    


 
Je pense que tu as bien ciblé ma demande en répondant autour de ce type énumératif bloquant dans le code.
Le fait est que l'on doit faire une sortie (get) sur un type énumératif, t_rubrique.
 

Code :
  1. TYPE T_Rubrique IS (Salaire, Versement, Loisirs, Maison, Divers);


 
Si je comprends ton code, je peux mettre salaire, versement ou loisirs... dans ta chaine de caractère sans me soucier de la longueur (car variable la longueur...) tant qu'elle est inférieur ou égalé à 10 ?

Reply

Marsh Posté le 05-12-2006 à 18:20:27    

Ok, j'avais pas fais attention,
 
Pourquoi le nom de T_NbLignes, ça veux dire quoi Nb
T_NbLignes je suppose, devrait s'appeler T_Ligne(s)_Comptable, ... un ligne est une ligne .. une chaine ... quelquonque, T_Ligne(s)_Comptable ... un ligne comptable et, T_NbLignes_Comptable devrait s'appeler T_Tab_Ligne(s)_Comptable.
Moi je ferais comme ça. Le (s) c'est soit tu parle de l'objet ... donc au singulié ... soit tu parle de l'ensemble des objet ... de la classe ... et c'est au pluriel. Mais c'est perso
 
Si non c'est bon... besoin d'autre chose ...  :heink:

Reply

Marsh Posté le 05-12-2006 à 18:26:59    

stupid_coder a écrit :

Je pense que tu as bien ciblé ma demande en répondant autour de ce type énumératif bloquant dans le code.
Le fait est que l'on doit faire une sortie (get) sur un type énumératif, t_rubrique.
 

Code :
  1. TYPE T_Rubrique IS (Salaire, Versement, Loisirs, Maison, Divers);


 
Si je comprends ton code, je peux mettre salaire, versement ou loisirs... dans ta chaine de caractère sans me soucier de la longueur (car variable la longueur...) tant qu'elle est inférieur ou égalé à 10 ?


 
Oui, tout à fait ... me semble t-il, à moins que j'ai oublié un détail.

Reply

Marsh Posté le 05-12-2006 à 18:32:23    

pour etre exact, c'est ::=
 

Code :
  1. -- j'ai oublié d'oter 1 à last_char
  2. Tab_B.Rubrique := T_Rubrique'value(to_uper(Rubrique(1..last_char-1)));


 
Mais je sais plus, il faut que je teste  :pt1cable:
 
Voila j'ai testé et c'est faux, c'est bien "Tab_B.Rubrique := T_Rubrique'value(to_uper(Rubrique(1..last_char)));" qu'il faut ecrire.


Message édité par Profil supprimé le 05-12-2006 à 18:46:08
Reply

Marsh Posté le 05-12-2006 à 18:35:02    


 
Oui effectivement j'utilise "tab_..." pour un tableau et "T_..." pour un type en temps normal...
Ensuite je voulais faire simple sans faire attention à une quelconque formalisation, qui dit au passage est très très bien pour la lecture du code comme pour sa compréhension.
 
Le "Nb" et autres font référence aux consignes de l'exercice, bête et discipliné...

Reply

Marsh Posté le 05-12-2006 à 18:44:16    

j'utilise Nbr comme abréviation de Nombre, c'est pour ça que je te demandais ça.
 
Si non, c'est bien "Tab_B.Rubrique := T_Rubrique'value(to_uper(Rubrique(1..last_char)));" et non pas "Tab_B.Rubrique := T_Rubrique'value(to_uper(Rubrique(1..last_char-1)));

Reply

Marsh Posté le 05-12-2006 à 18:48:25    

stupid_coder a écrit :

Oui effectivement j'utilise "tab_..." pour un tableau et "T_..." pour un type en temps normal...
Ensuite je voulais faire simple sans faire attention à une quelconque formalisation, qui dit au passage est très très bien pour la lecture du code comme pour sa compréhension.
 
Le "Nb" et autres font référence aux consignes de l'exercice, bête et discipliné...


 
Parce qu'un "type 'tableau' is array () of ..... " c'est pas un type peut-etre ??  :heink:

Reply

Marsh Posté le 05-12-2006 à 18:53:41    

je sais je sais... il y a "type" et "type".
Le tableau est spécial pour moi.
Il est définit en temps que conteneur, regroupe des données, donc je lui attribue une place de choix dans le code, bien distinguer les types et... les types tableaux !

Reply

Marsh Posté le 05-12-2006 à 18:55:02    

Ma foix ....
 
Bonsoir coder

Reply

Marsh Posté le 05-12-2006 à 19:02:48    

je risque de reposter après avoir fait un petit lifting au code, en fin de soirée...
bonne soirée...

Reply

Marsh Posté le 05-12-2006 à 19:11:51    

Ok, je repasse plus tard ...  

Reply

Marsh Posté le 07-12-2006 à 20:29:47    


 
Bonjour Jovalise,
 
J'ai fait le lifting comme prévu.
Cependant j'obtiens un "constraint_error explicit raise" durant l'execution du programme, je valide une valeur décimale ( Get(tab_b.Valeur); ) et après c'est le drame...
 
J'utilise la déclaration suivante :
 

Code :
  1. /*<<<<<<<<<<<<<<<Pour utilisation du type t_rubrique>>>>>>>>>>>>>>>>>>*/
  2.    max_T_Rubrique : Constant Integer := 10;
  3.    str_Rubrique : String (1..max_T_Rubrique) := (OTHERS => Ascii.Nul);
  4.    Last_Char : Natural := 0;
  5. /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>*/


 
Au passage j'aimerais connaitre le " OTHERS => Ascii.Nul" . Kesako ?
 
Ensuite, avant le begin je déclare les variables suivantes, elles ne changent pas je crois :
 

Code :
  1. /* toujours pas de formalisation... */
  2. lignes_A:T_Nblignes_Comptable;
  3.       tab_B:t_Nblignes;


 
Je reprends ton appel get_line avec mes variables:
 

Code :
  1. /*rien d'anormal jusqu'ici je pense... */
  2. Get_Line(str_Rubrique,Last_Char);


 
Pour finir, j'ai refais une partie de la dernière ligne car celle que tu proposais ne mentionnais pas le type "T_Nblignes_Comptable" représenté par "lignes_A "
Comme c'est un tableau indicé, nous avons :
 

Code :
  1. /* nous affectons la valeur T_Rubrique'Value(To_Upper(str_Rubrique(1..Last_Char à l'adresse mémoire lignes_A(i).Rubrique .A noter to_upper avec 2 "p" :) */
  2. lignes_A(i).Rubrique := T_Rubrique'Value(To_Upper(str_Rubrique(1..Last_Char)));


Pas de problème de compilation mais un "CONSTRAINT_ERROR EXPLICIT RAISE" comme annoncé au début.
 
Je me trompe surement avec le type t_nblignes, qui est un record avec notre fameux type énumératif t_rubrique, et le str_rubrique qui est un string.
 
Je comprends pas toute la ligne T_Rubrique'Value(To_Upper(str_Rubrique(1..Last_Char))); :
str_Rubrique(1..Last_Char) valeur du get_line gardé en mémoire -ok
To_Upper on met en majuscule les caractères -ok
T_Rubrique'Value est la transformatioin d'un type string en type t_rubrique car rubrique est un string jusqu'ici...
 
Merci de tes réponses, je continue à bucher dessus...


---------------
...pour les miracles ? prévoir un délai !
Reply

Marsh Posté le 07-12-2006 à 23:18:36    

stupid_coder a écrit :


Au passage j'aimerais connaitre le " OTHERS => Ascii.Nul" . Kesako ?


 
ben on affecte le caractere nul au reste des variable, comme on specifit pas de variable en particulier OTHERS represente toute les variables.
 

stupid_coder a écrit :


Ensuite, avant le begin je déclare les variables suivantes, elles ne changent pas je crois :
 

Code :
  1. /* toujours pas de formalisation... */
  2. lignes_A:T_Nblignes_Comptable;
  3.       tab_B:t_Nblignes;


 
Je reprends ton appel get_line avec mes variables:
 

Code :
  1. /*rien d'anormal jusqu'ici je pense... */
  2. Get_Line(str_Rubrique,Last_Char);


 
Pour finir, j'ai refais une partie de la dernière ligne car celle que tu proposais ne mentionnais pas le type "T_Nblignes_Comptable" représenté par "lignes_A "
Comme c'est un tableau indicé, nous avons :
 

Code :
  1. /* nous affectons la valeur T_Rubrique'Value(To_Upper(str_Rubrique(1..Last_Char à l'adresse mémoire lignes_A(i).Rubrique .A noter to_upper avec 2 "p" :) */
  2. lignes_A(i).Rubrique := T_Rubrique'Value(To_Upper(str_Rubrique(1..Last_Char)));




Tout ceci semble correct ... de memoire ...

stupid_coder a écrit :


Je comprends pas toute la ligne T_Rubrique'Value(To_Upper(str_Rubrique(1..Last_Char))); :


On affecte la valeur retourné par l'attribut 'Value auquel on donne la mise en majuscule de la valeur du tableau de caracteres str_Rubrique du premier au dernier caractere saisie au clavier ou ailleur à la variablr Rubrique numéro i du tableau Ligne_A.

stupid_coder a écrit :


T_Rubrique'Value est la transformatioin d'un type string en type t_rubrique car rubrique est un string jusqu'ici...


c'est pas la transformation, c'est une fonctionnalité Ada, une transformation serait ::=  
Rubrique := t_rubrique(str_Rubrique(1..Last_Char))
C'est une conversion, mais Ada, n'accepte pas cette conversion.
l'attribut 'Value propose de prendre la representation source "graphique" accepté par le langage des valeur du type et de retourner la valeur correspondante du type de base du type de Rubrique.
 
 
Je regarde ce qui ne va pas exactement d'ici demain  :hello:


Message édité par Profil supprimé le 07-12-2006 à 23:26:15
Reply

Marsh Posté le 08-12-2006 à 09:13:49    

:hello: Bonjour,
 
A priori, il suffit d'inserer un "Skip_Line" avant de faire le get de rubrique, et ça roule.


Message édité par Profil supprimé le 08-12-2006 à 09:14:07
Reply

Marsh Posté le 08-12-2006 à 10:34:19    

yes! je vais essayer et je te tiens au courant.
merci

Reply

Marsh Posté le 08-12-2006 à 19:21:50    

c'est bien ça !
Je reviendrais prendre quelques consils, tu est efficace Jovalise, merci encore !

Reply

Marsh Posté le 08-12-2006 à 19:31:58    

yé, à plus coder  :jap:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed