Forums Rue-Montgallet.com
Rue-Montgallet.comRue-Hardware.comRue-Occasion.comRue-DVD.comRue-Jeuxvideo.comRue-AudioVideo.comRue-Telephone.comForums
S'inscrire | S'identifier |
| Recherche avancée | Aide
 
 

Il y a 50 utilisateurs connus et inconnus. Pour voir la liste des connectés connus, cliquez ici

 Mot :   Pseudo :  
 
Bas de page
Auteur
 Sujet :

mot de passe

 
n°17978
aaargh
Profil : Jeune recrue
Posté le 04-12-2006 à 11:38:26  profilanswer
 

Bonjour
je dois realiser un programme en c gestion de comptes bancaires et dois par la meme occasion creer un e mot de passe pour les utilisateurs des comptes ...
Je n'arrive vraiment pas à le faire
est-ce que qn pourrait m'aider ???
 
ca serait vraiment genial
Merci d'avance
 
aaargh

n°17982
-ed-
C is a sharp tool
Profil : Jeune recrue
Posté le 04-12-2006 à 16:01:48  profilanswer
 

aaargh a écrit :

Je n'arrive vraiment pas à le faire
est-ce que qn pourrait m'aider ???


Tu as oublié de poster le code avec lequel tu as un problème. Si il n'y a pas de code, poste au moins les études préalables :  
 
1 - Spécifications (on a une vague idée, mais ça demande des précisions : système, environnement...)
2 - Conception (comment résoudre les problèmes exposés en 1)
 
On ne code pas au hasard...


Message édité par -ed- le 04-12-2006 à 16:02:38

---------------
Emmanuel Delahaye
Des infos sur la programmation et le langage C:
http://bien-programmer.blogspot.com/  
http://mapage.noos.fr/emdel/
n°17983
aaargh
Profil : Jeune recrue
Posté le 04-12-2006 à 17:47:27  profilanswer
 


Voici le code que l'on a fait j'ai tout mis ca fait surement bcp la !
il y a 600lignes en gros, maintenant on a des structures, comptes, banques ...  
ce que l'on doit faire c'est insérer les mots de passe pour les comptes : l'ecran indique qu'il faut que le titulaire rentre un mot de passe qu'il le confirme, puis a chaque utilisation du code il faut lui redemander et verifier s'il est bon, on veut faire un seul code pour chaque titulaire, qui pourra avoir plusieur comptes.
Sinon on doit pouvoir faire des virements d'un compte a l'autre mais c'est lamot de passe qui nous embete plus !
voilà j'espere vraiment que l'on pourra nous aider .
Aaargh
 
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <time.h>
  6. #define LONG_TITU 40
  7. #define MAX_COMPTES 256
  8. #define NB_OPS 4
  9. /* codage des operations */
  10. #define NO_OP 0
  11. #define OUVERTURE 1
  12. #define DEPOT 2
  13. #define RETRAIT 3
  14. #define CLOTURE 4
  15. /* codage des etats de compte */
  16. #define LIBRE 0
  17. #define OUVERT 1
  18. #define CLOS 2
  19. #ifdef linux
  20. #include <stdio_ext.h>
  21. #define PURGE(X) __fpurge(X)
  22. #else
  23. #ifdef __DARWIN_NULL
  24. #define PURGE(X) fpurge(X)
  25. #else
  26. #define PURGE(X) fflush(X)
  27. #endif
  28. #endif
  29. /**************************************************************/
  30. /* le type "operation" */
  31. struct operation {
  32.         double montant;
  33.         int type; /* NO_OP, OUVERTURE... */
  34.         time_t date; /* date au format "systeme" */
  35. };
  36. /* le type "compte" */
  37. struct compte {
  38.         int numero;
  39.         char titulaire[LONG_TITU];
  40.         int etat; /* LIBRE, OUVERT, CLOS */
  41.         double solde;
  42.         struct operation ops[NB_OPS];
  43. };
  44. /* NB : dans le tableau ops, les operations sont classees par */
  45. /* ordre de saisie decroissant, la derniere operation saisie */
  46. /* est toujours ops[0] */
  47. /* le type "agence" */
  48. struct agence {
  49.         double solde;
  50.         int num_prochain_compte;
  51.         struct compte comptes[MAX_COMPTES];
  52. };
  53. /**************************************************************/
  54. /* fonction d'initialisation de l'agence                      */
  55. /**************************************************************/
  56. void raz_agence (struct agence *ag)
  57. {
  58. int i;
  59.         ag->solde=0.;
  60.         ag->num_prochain_compte=0;
  61.         for (i=0;i<MAX_COMPTES;i++)
  62.                 ag->comptes[i].etat=LIBRE;
  63. }
  64. /* fonction de remise a zero d'un compte (utilise par purge)  */
  65. void raz_compte (struct compte *cpt)
  66. {
  67. int i;
  68.         cpt->numero=0;
  69.         memset(cpt->titulaire,0,LONG_TITU);
  70.         cpt->etat=0;
  71.         cpt->solde=0.;
  72.         for (i=0;i<NB_OPS;i++) {
  73.                 cpt->ops[i].montant=0.;
  74.                 cpt->ops[i].type=NO_OP;
  75.                 cpt->ops[i].date=0;
  76.         }
  77. }
  78. /**************************************************************/
  79. /* fonctions de lecture/ecriture d'une agence dans un fichier */
  80. /**************************************************************/
  81. int charge_agence (char *nomfichier, struct agence *ag)
  82. {
  83. FILE *pf;
  84. size_t sz;
  85. int status;
  86.         /* on ouvre le fichier en lecture seule */
  87.         pf=fopen(nomfichier,"r" );
  88.         if (pf==NULL)
  89.                 return -1;
  90.         sz=sizeof(struct agence);
  91.         /* on lit une structure de taille sz que l'on */
  92.         /* stocke a l'adresse indiquee par ag */
  93.         if (fread(ag,sz,1,pf)==1)
  94.                 status=0;
  95.         else
  96.                 status=-1;
  97.         fclose(pf);
  98.         return status;
  99. }
  100. int sauve_agence (char *nomfichier, struct agence *ag)
  101. {
  102. FILE *pf;
  103. size_t sz;
  104. int status;
  105.         /* on ouvre le fichier en (re)ecriture */
  106.         pf=fopen(nomfichier,"w" );
  107.         if (pf==NULL)
  108.                 return -1;
  109.         sz=sizeof(struct agence);
  110.         /* on ecrit la structure de taille sz stockee */
  111.         /* a l'adresse indiquee par ag */
  112.         if (fwrite(ag,sz,1,pf)==1)
  113.                 status=0;
  114.         else
  115.                 status=-1;
  116.         fclose(pf);
  117.         return status;
  118. }
  119. /*******************************************************/
  120. /* Diverses fonctions de recherche                     */
  121. /*******************************************************/
  122. /* le resultat est l'adresse du compte, NULL en cas de */
  123. /* non-existence du compte. Attention : le compte peut */
  124. /* etre CLOS ! */
  125. /* fonction de recherche d'un compte par son numero    */
  126. struct compte *cherche_cpt_num (struct agence *ag,int numcpt)
  127. {
  128. int i;
  129.         for (i=0;i<MAX_COMPTES;i++)
  130.                 if (((ag->comptes[i].etat==OUVERT)||
  131.                         (ag->comptes[i].etat==CLOS))&&
  132.                         (ag->comptes[i].numero==numcpt))
  133.                         return &(ag->comptes[i]);
  134.         return 0;
  135. }
  136. /* fonction de recherche d'un compte par son titulaire */
  137. struct compte *cherche_cpt_titu (struct agence *ag,char *titu)
  138. {
  139. int i;
  140.         for (i=0;i<MAX_COMPTES;i++)
  141.                 if (((ag->comptes[i].etat==OUVERT)||
  142.                         (ag->comptes[i].etat==CLOS))&&
  143.                         (!strcmp(ag->comptes[i].titulaire,titu)))
  144.                         return &(ag->comptes[i]);
  145.         return 0;
  146. }
  147. /* fonction de recherche d'un compte libre             */
  148. struct compte *cherche_cpt_libre (struct agence *ag)
  149. {
  150. int i;
  151.         for (i=0;i<MAX_COMPTES;i++)
  152.                 if (ag->comptes[i].etat==LIBRE)
  153.                         return &(ag->comptes[i]);
  154.         return 0;
  155. }
  156. /*******************************************************/
  157. /* fonctions de traitement                             */
  158. /*******************************************************/
  159. /* ouverture d'un compte pour titu a la date t         */
  160. /* la fonction rend : numero de compte si tout est OK, */
  161. /* -1 si l'agence est "complete", -2 si le titulaire a */
  162. /* deja un compte                                      */
  163. int traite_ouverture (struct agence *ag,char *titu,time_t t)
  164. {
  165. int i;
  166. struct compte *cpt;
  167.         /* on verifie d'abord que le titulaire n'a pas */
  168.         /* deja un compte                              */
  169.         cpt=cherche_cpt_titu(ag,titu);
  170.         if (cpt)
  171.                 return -2;
  172.         cpt=cherche_cpt_libre(ag);
  173.         if (!cpt)
  174.                 return -1;
  175.         /* on remplit les champs du compte cree */
  176.         cpt->numero=ag->num_prochain_compte++;
  177.         strncpy(cpt->titulaire,titu,LONG_TITU-1);
  178.         cpt->etat=OUVERT;
  179.         cpt->solde=0.;
  180.         /* on remplit l'operation 0 de type OUVERTURE */
  181.         cpt->ops[0].type=OUVERTURE;
  182.         cpt->ops[0].date=t;
  183.         cpt->ops[0].montant=0.;
  184.         /* on remplit les operations suivantes avec NO_OP */
  185.         for (i=1;i<NB_OPS;i++)
  186.                 cpt->ops[i].type=NO_OP;
  187.         return cpt->numero;
  188. }
  189. /* fonction de traitement de l'operation op sur le compte */
  190. /* de numero numcpt de l'agence ag (op != OUVERTURE)      */
  191. int traite_operation (struct agence *ag,int numcpt,
  192.         struct operation *op)
  193. {
  194. int i;
  195. struct compte *cpt;
  196.         /* on cherche le compte de numero numcpt */
  197.         cpt=cherche_cpt_num(ag,numcpt);
  198.         /* test de validite : compte inexistant ou CLOS */
  199.         if ((cpt==0)||(cpt->etat==CLOS))
  200.                 return -1;
  201.         switch (op->type) {
  202.                 case DEPOT:
  203.                         cpt->solde+=op->montant;
  204.                         ag->solde+=op->montant;
  205.                         break;
  206.                 case RETRAIT:
  207.                         if (cpt->solde < op->montant)
  208.                                 return -1;
  209.                         cpt->solde-=op->montant;
  210.                         ag->solde-=op->montant;
  211.                         break;
  212.                 case CLOTURE:
  213.                         if (cpt->solde!=0)
  214.                                 return -1;
  215.                         cpt->etat=CLOS;
  216.                         break;
  217.                 default:
  218.                         return -1;
  219.         }
  220.         /* on "decale" les operations du tableau ops */
  221.         for (i=NB_OPS-2;i>=0;i--)
  222.                 cpt->ops[i+1]=cpt->ops[i];
  223.         cpt->ops[0]= *op;
  224.         return 0;
  225. }
  226. /* fonction d'affichage du solde de l'agence             */
  227. void solde_agence (struct agence *ag)
  228. {
  229.         printf("Le solde de l'agence est %.2f\n",ag->solde);
  230. }
  231. /* fonction de "purge" de l'agence : libere les comptes  */
  232. /* CLOS avant la date t */
  233. void purge_agence (struct agence *ag,time_t t)
  234. {
  235. int i,nb;
  236.         for (i=0,nb=0;i<MAX_COMPTES;i++)
  237.                 /* si le compte est CLOS, et que la cloture a eu */
  238.                 /* lieu avant "cur", on remet a zero le compte */
  239.                 if ((ag->comptes[i].etat==CLOS) &&
  240.                         (ag->comptes[i].ops[0].date < t)) {
  241.                         printf("Purge du compte %d\n",
  242.                                 ag->comptes[i].numero);
  243.                         raz_compte(&(ag->comptes[i]));
  244.                         nb++;
  245.                 }
  246.         printf("%d comptes purges\n",nb);
  247. }
  248. /* effectue un releve de l'operation op. le format est :    */
  249. /* JJ/MM/AAAA HH:MM ouverture/cloture/[depot,retrait] de XX */
  250. /* on utilise localtime pour convertir les dates            */
  251. void releve_operation (struct operation *op)
  252. {
  253. struct tm *d;
  254.         if (op->type==NO_OP)
  255.                 return;
  256.         d=localtime(&(op->date));
  257.         if (d==0)
  258.                 fputs("\tXX/XX/XXXX XX:XX ",stdout);
  259.         else
  260.                 printf("\t%02d/%02d/%04d %02d:%02d ",
  261.                         d->tm_mday,d->tm_mon+1,d->tm_year+1900,
  262.                         d->tm_hour,d->tm_min);
  263.         switch (op->type) {
  264.                 case OUVERTURE:
  265.                         fputs("ouverture\n",stdout);
  266.                         return;
  267.                 case CLOTURE:
  268.                         fputs("cloture\n",stdout);
  269.                         return;
  270.                 case DEPOT:
  271.                         printf("depot de %.2f E\n",op->montant);
  272.                         return;
  273.                 case RETRAIT:
  274.                         printf("retrait de %.2f E\n",op->montant);
  275.                         return;
  276.         }
  277. }
  278. /* fonction de releve du compte de numero numcpt           */
  279. /* on affiche les informations du compte, puis les NB_OPS  */
  280. /* (au plus) dernieres operations                          */
  281. int releve_compte (struct agence *ag,int numcpt)
  282. {
  283. struct compte *cpt;
  284. int i;
  285.         cpt=cherche_cpt_num(ag,numcpt);
  286.         if (!cpt)
  287.                 return -1;
  288.         printf("Titulaire : %s\n",cpt->titulaire);
  289.         printf("Compte %d",cpt->numero);
  290.         if (cpt->etat==CLOS)
  291.                 fputs(" [CLOTURE]\n",stdout);
  292.         else
  293.                 printf(", solde %.2f E\n",cpt->solde);
  294.         for (i=NB_OPS-1;i>=0;i--)
  295.                 releve_operation(&(cpt->ops[i]));
  296.         return 0;
  297. }
  298. /*********************************************************/
  299. /* Diverses fonctions de saisie au clavier               */
  300. /* ces fonctions rendent -1 en cas d'annulation (CTRL-D  */
  301. /* frappe au clavier), sinon elles insistent indefiniment*/
  302. /* pour avoir une saisie "correcte"                      */
  303. /*********************************************************/
  304. int saisie_num_cpt (void)
  305. {
  306. int num;
  307. char rep[1024];
  308.         for (;;) {
  309.                 fputs("Numero de compte"
  310.                         " (CTRL-D pour annuler) ? ",stdout);
  311.                 PURGE(stdin);
  312.                 if (!fgets(rep,1024,stdin)) {
  313.   clearerr(stdin);
  314.                         return -1;
  315.  }
  316.                 if (sscanf(rep,"%d",&num)==1)
  317.                         return num;
  318.         }
  319. }
  320. int saisie_code_op (void)
  321. {
  322. char rep[1024];
  323.         for (;;) {
  324.                 fputs("D(epot), R(etrait), C(loture)"
  325.                         " (CTRL-D pour annuler) ? ",stdout);
  326.                 PURGE(stdin);
  327.                 if (!fgets(rep,1024,stdin)) {
  328.   clearerr(stdin);
  329.                         return -1;
  330.  }
  331.                 switch (rep[0]) {
  332.                         case 'D':
  333.                                 return DEPOT;
  334.                         case 'R':
  335.                                 return RETRAIT;
  336.                         case 'C':
  337.                                 return CLOTURE;
  338.                         default:
  339.                                 break;
  340.                 }
  341.         }
  342. }
  343. int saisie_titulaire (char *titu)
  344. {
  345. char *eol;
  346.         fputs("Titulaire (CTRL-D pour annuler) ? ",stdout);
  347.         PURGE(stdin);
  348.         if (!fgets(titu,LONG_TITU,stdin)) {
  349.  clearerr(stdin);
  350.                 return -1;
  351. }
  352.         /* on tronque le nom au premier saut de ligne      */
  353.         eol=strchr(titu,'\n');
  354.         if (eol)
  355.                 eol[0]=0;
  356.         return 0;
  357. }
  358. int saisie_montant (double *v)
  359. {
  360. char rep[1024];
  361.         for (;;) {
  362.                 fputs("Montant"
  363.                         " (CTRL-D pour annuler) ? ",stdout);
  364.                 PURGE(stdin);
  365.                 if (!fgets(rep,1024,stdin)) {
  366.   clearerr(stdin);
  367.                         return -1;
  368.  }
  369.                 if (sscanf(rep,"%lf",v)==1)
  370.                         return 1;
  371.         }
  372. }
  373. /* fonction de saisie de date                            */
  374. /* la date est saisie sous la forme JJ/MM/AAAA HH:MM     */
  375. /* la fonction propose la date courante, si l'utilisateur*/
  376. /* ne tape rien (<Return> ou CTRL-D), on accepte cette   */
  377. /* date courante                                         */
  378. time_t saisie_date (void)
  379. {
  380. time_t t;
  381. struct tm *d,buf;
  382. char rep[1024];
  383.         for (;;) {
  384.                 t=time(0);
  385.                 d=localtime(&t);
  386.                 fputs("Date ",stdout);
  387.                 if (d)
  388.                         printf("(%02d/%02d/%04d %02d:%02d) ? ",
  389.                                 d->tm_mday,1+d->tm_mon,d->tm_year+1900,
  390.                                 d->tm_hour,d->tm_min);
  391.                 PURGE(stdin);
  392.                 if (!fgets(rep,1024,stdin) || (rep[0]=='\n')) {
  393.   clearerr(stdin);
  394.                         return t;
  395.  }
  396.                 if (sscanf(rep," %d/%d/%d %d:%d",
  397.                         &(buf.tm_mday),&(buf.tm_mon),&(buf.tm_year),
  398.                         &(buf.tm_hour),&(buf.tm_min))==5) {
  399.                         buf.tm_mon--;
  400.                         buf.tm_year-=1900;
  401.                         buf.tm_sec=0;
  402.                         buf.tm_isdst=-1;
  403.                         return mktime(&buf);
  404.                 }
  405.         }
  406. }
  407. /*********************************************************/
  408. /* Les differents menus pour saisir les infos et traiter */
  409. /*********************************************************/
  410. void menu_recherche (struct agence *ag)
  411. {
  412. char titu[LONG_TITU];
  413. struct compte *cpt;
  414. int num;
  415.         for (;;) {
  416.                 puts("[Comptes/Recherche de compte]" );
  417.                 if (saisie_titulaire(titu)==-1)
  418.                         return;
  419.                 cpt=cherche_cpt_titu(ag,titu);
  420.                 if (cpt) {
  421.                         printf("compte %d, titulaire %s\n",
  422.                                 cpt->numero,cpt->titulaire);
  423.                         return;
  424.                 }
  425.                 /* on essaie d'interpreter le titulaire */
  426.                 /* comme un numero de compte            */
  427.                 if (sscanf(titu,"%d",&num)==1) {
  428.                         cpt=cherche_cpt_num(ag,num);
  429.                         if (cpt) {
  430.                                 printf("compte %d, titulaire %s\n",
  431.                                         cpt->numero,cpt->titulaire);
  432.                                 return;
  433.                         }
  434.                 }
  435.                 fputs("NON TROUVE\n",stdout);
  436.                 return;
  437.         }
  438. }
  439. void menu_saisie_op (struct agence *ag)
  440. {
  441. struct operation op;
  442. int num_cpt;
  443.         for (;;) {
  444.                 puts("[Comptes/Saisie d'operation]" );
  445.                 num_cpt=saisie_num_cpt();
  446.                 if (num_cpt==-1)
  447.                         return;
  448.                 op.type=saisie_code_op();
  449.                 if (op.type==-1)
  450.                         return;
  451.                 if (op.type!=CLOTURE)
  452.                         if (saisie_montant(&(op.montant))==-1)
  453.                                 return;
  454.                 op.date=saisie_date();
  455.                 if (traite_operation(ag,num_cpt,&op)==-1)
  456.                         printf("Echec du traitement !\n" );
  457.                 else
  458.                         printf("Traitement effectue !\n" );
  459.                         return;
  460.         }
  461. }
  462. void menu_releve (struct agence *ag)
  463. {
  464. int num_cpt;
  465.         for (;;) {
  466.                 puts("[Comptes/Releve de compte]" );
  467.                 num_cpt=saisie_num_cpt();
  468.                 if (num_cpt==-1)
  469.                         return ;
  470.                 if (releve_compte(ag,num_cpt)==-1)
  471.                         fputs("COMPTE INEXISTANT\n",stdout);
  472.                         return ;
  473.         }
  474.        
  475. }
  476. void menu_ouverture (struct agence *ag)
  477. {
  478. char titu[LONG_TITU];
  479. int num;
  480. time_t t;
  481.         for (;;) {
  482.                 puts("[Comptes/Ouverture]" );
  483.                 if (saisie_titulaire(titu)==-1)
  484.                         return;
  485.                 t=saisie_date();
  486.                 switch (num=traite_ouverture(ag,titu,t)) {
  487.                         case -2:
  488.                                 puts("CE TITULAIRE A DEJA UN COMPTE" );
  489.                                 return;
  490.                         case -1:
  491.                                 puts("L'AGENCE EST COMPLETE" );
  492.                                 return;
  493.                         default:
  494.                                 printf("compte %d cree\n",num);
  495.                                 return;
  496.                 }
  497.         }
  498. }
  499. void menu_purge (struct agence *ag)
  500. {
  501. time_t tpurge;
  502. char dummy[1024];
  503. puts("[ATTENTION : purge des comptes (CTRL-D pour annuler)]" );
  504. PURGE(stdin);
  505. if (!fgets(dummy,1024,stdin)) {
  506.  clearerr(stdin);
  507.  return;
  508. }
  509. tpurge=saisie_date();
  510. purge_agence(ag,tpurge);
  511. }
  512. void menu_comptes (struct agence *ag)
  513. {
  514. char rep[1024];
  515. int choix;
  516.         for (;;) {
  517.                 puts("[Comptes]" );
  518.                 puts("(1) recherche d'un numero de compte" );
  519.                 puts("(2) saisie d'une operation" );
  520.                 puts("(3) releve de compte" );
  521.                 puts("(4) ouverture de compte" );
  522.                 puts("(0) sortie" );
  523.                 fputs("--> ",stdout);
  524.                 PURGE(stdin);
  525.                 if (!fgets(rep,1024,stdin)) {
  526.   clearerr(stdin);
  527.                         return;
  528.  }
  529.                 if (sscanf(rep,"%d",&choix)!=1)
  530.                         continue;
  531.                 switch (choix) {
  532.                         case 0:
  533.                                 return;
  534.                         case 1:
  535.                                 menu_recherche(ag);
  536.                                 break;
  537.                         case 2:
  538.                                 menu_saisie_op(ag);
  539.                                 break;
  540.                         case 3:
  541.                                 menu_releve(ag);
  542.                                 break;
  543.                         case 4:
  544.                                 menu_ouverture(ag);
  545.                                 break;
  546.                         default:
  547.                                 printf("Mauvais choix %s !\n",rep);
  548.                                 break;
  549.                 }
  550.         }
  551. }
  552. void menu_principal (struct agence *ag)
  553. {
  554. char rep[1024];
  555. int choix;
  556.         for (;;) {
  557.                 puts("(1) consultation du solde agence" );
  558.                 puts("(2) acces au menu 'comptes'" );
  559.                 puts("(3) purge des comptes" );
  560.                 puts("(4) SORTIE IMMEDIATE SANS SAUVEGARDE" );
  561.  puts("(5) remise a zero de l'agence" );
  562.                 printf("(0) sortie\n--> " );
  563.                 PURGE(stdin);
  564.                 if (!fgets(rep,1024,stdin)) {
  565.   clearerr(stdin);
  566.                         continue;
  567.  }
  568.                 if (sscanf(rep,"%d",&choix)!=1)
  569.                         continue;
  570.                 switch (choix) {
  571.                         case 0:
  572.                                 return;
  573.                         case 1:
  574.                                 solde_agence(ag);
  575.                                 break;
  576.                         case 2:
  577.                                 menu_comptes(ag);
  578.                                 break;
  579.                         case 3:
  580.                                 menu_purge(ag);
  581.                                 break;
  582.                         case 4:
  583.                                 exit(1);
  584.                                 /*NOTREACHED*/
  585.                                 return;
  586.   case 5:
  587.    raz_agence(ag);
  588.    break;
  589.                         default:
  590.                                 break;
  591.                 }
  592.         }
  593.         return;
  594. }
  595. int main (int argc,char *argv[])
  596. {
  597. char *fic_agence;
  598. struct agence ag;
  599. char rep[1024];
  600.         if (argc==1)
  601.                 fic_agence="agence.dat";
  602.         else
  603.                 fic_agence=argv[1];
  604.         if (charge_agence(fic_agence,&ag)==-1) {
  605.                 perror(fic_agence);
  606.                 printf("Initialise une agence vide ?" );
  607.                 if (fscanf(stdin,"%s",rep)!=1) {
  608.                         perror("stdin" );
  609.                         fprintf(stderr,"STOP !!!\n" );
  610.                         return 2;
  611.                 }
  612.                 if (rep[0]=='o' || rep[0]=='O' || rep[0]=='y' ||
  613.                         rep[0]=='Y')
  614.                         raz_agence(&ag);
  615.                 else {
  616.                         fprintf(stderr,"STOP !!!\n" );
  617.                         return 2;
  618.                 }
  619.         }
  620.         menu_principal(&ag);
  621.         if (sauve_agence(fic_agence,&ag)==-1) {
  622.                 perror(fic_agence);
  623.                 return 1;
  624.         }
  625.         return 0;
  626. }

n°17984
-ed-
C is a sharp tool
Profil : Jeune recrue
Posté le 04-12-2006 à 20:00:25  profilanswer
 

aaargh a écrit :

Voici le code que l'on a fait j'ai tout mis ca fait surement bcp la !


Oui, tu aurais pu réduire au problème précis. Tant pis, tu vas te prendre une revue de code, ça ne fait pas de mal...

Citation :


il y a 600lignes en gros, maintenant on a des structures, comptes, banques ...  
ce que l'on doit faire c'est insérer les mots de passe pour les comptes : l'ecran indique qu'il faut que le titulaire rentre un mot de passe qu'il le confirme, puis a chaque utilisation du code il faut lui redemander et verifier s'il est bon, on veut faire un seul code pour chaque titulaire, qui pourra avoir plusieur comptes.
Sinon on doit pouvoir faire des virements d'un compte a l'autre mais c'est lamot de passe qui nous embete plus !
voilà j'espere vraiment que l'on pourra nous aider .


Voilà du code assez bien fait. Il y a quelques points à revoir, notamment au niveau des saisies, mais c'est plutôt bien analysé et bien construit, dans un esprit OO.
 

  • Attention, la sauvegarde des données 'brutes' n'est pas portable.


http://mapage.noos.fr/emdel/notes.htm#enreg_struct
 

  • Les entrées sont basées sur fgets(). C'est bien, mais c'est insuffisant. Il faut ensuite (et pas avant) nettoyer le flux si nécessaire et en profiter pour supprimer le \n. Je recommande la fonction fclean() (code minimum ci-après)


  • Attention a ne pas sur-dimensionner les chaines de saisie (1k dans la mémoire auto à chaque fois, c'est beaucoup). La taille devrait être déterminée avec l'opérateur sizeof (tableaux statiques).


  • Il est préférable de n'avoir qu'un return par fonction. Le code est plus clair et il y a moins de risque d'erreur de libération de ressource.


Ton code commenté et corrigé.

Code :
  1. /*
  2. Voici le code que l'on a fait j'ai tout mis ca fait surement bcp la !
  3. il y a 600lignes en gros, maintenant on a des structures, comptes, banques ...
  4. ce que l'on doit faire c'est insérer les mots de passe pour les comptes : l'ecran indique qu'il faut que le titulaire rentre un mot de passe qu'il le confirme, puis a chaque utilisation du code il faut lui redemander et verifier s'il est bon, on veut faire un seul code pour chaque titulaire, qui pourra avoir plusieur comptes.
  5. Sinon on doit pouvoir faire des virements d'un compte a l'autre mais c'est lamot de passe qui nous embete plus !
  6. voilà j'espere vraiment que l'on pourra nous aider .
  7. Aaargh
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <sys/types.h>
  13. #include <time.h>
  14. #define LONG_TITU 40
  15. #define MAX_COMPTES 256
  16. #define NB_OPS 4
  17. /* codage des operations */
  18. #define NO_OP 0
  19. #define OUVERTURE 1
  20. #define DEPOT 2
  21. #define RETRAIT 3
  22. #define CLOTURE 4
  23. /* codage des etats de compte */
  24. #define LIBRE 0
  25. #define OUVERT 1
  26. #define CLOS 2
  27. /* -ed-
  28. #ifdef linux
  29. #include <stdio_ext.h>
  30. #define PURGE(X) __fpurge(X)
  31. #else
  32. #ifdef __DARWIN_NULL
  33. #define PURGE(X) fpurge(X)
  34. #else
  35. #define PURGE(X) fflush(X)
  36. #endif
  37. #endif
  38. Non ! fflush() n'est defini que pour les flux entrants...
  39. */
  40. /* -ed- a appeler apres un fgets() */
  41. static void fclean (char *s, FILE * fp)
  42. {
  43.    char *p = strchr (s, '\n');
  44.    if (p != NULL)
  45.    {
  46.       *p = 0;
  47.    }
  48.    else
  49.    {
  50.       int c;
  51.       while ((c = fgetc (fp)) != '\n' && c != EOF)
  52.       {
  53.       }
  54.    }
  55. }
  56. /**************************************************************/
  57. /* le type "operation" */
  58. struct operation
  59. {
  60.    double montant;
  61.    int type;                    /* NO_OP, OUVERTURE... */
  62.    time_t date;                 /* date au format "systeme" */
  63. };
  64. /* le type "compte" */
  65. struct compte
  66. {
  67.    int numero;
  68.    char titulaire[LONG_TITU];
  69.    int etat;                    /* LIBRE, OUVERT, CLOS */
  70.    double solde;
  71.    struct operation ops[NB_OPS];
  72. };
  73. /* NB : dans le tableau ops, les operations sont classees par */
  74. /* ordre de saisie decroissant, la derniere operation saisie */
  75. /* est toujours ops[0] */
  76. /* le type "agence" */
  77. struct agence
  78. {
  79.    double solde;
  80.    int num_prochain_compte;
  81.    struct compte comptes[MAX_COMPTES];
  82. };
  83. /**************************************************************/
  84. /* fonction d'initialisation de l'agence                      */
  85. /**************************************************************/
  86. /* -ed-
  87. void raz_agence (struct agence *ag)
  88. Fonction non exportee, donc 'static'
  89. */
  90. static void raz_agence (struct agence *ag)
  91. {
  92.    int i;
  93.    ag->solde = 0.;
  94.    ag->num_prochain_compte = 0;
  95.    for (i = 0; i < MAX_COMPTES; i++)
  96.       ag->comptes[i].etat = LIBRE;
  97. }
  98. /* fonction de remise a zero d'un compte (utilise par purge)  */
  99. static void raz_compte (struct compte *cpt)
  100. {
  101.    int i;
  102.    cpt->numero = 0;
  103.    memset (cpt->titulaire, 0, LONG_TITU);
  104.    cpt->etat = 0;
  105.    cpt->solde = 0.;
  106.    for (i = 0; i < NB_OPS; i++)
  107.    {
  108.       cpt->ops[i].montant = 0.;
  109.       cpt->ops[i].type = NO_OP;
  110.       cpt->ops[i].date = 0;
  111.    }
  112. }
  113. /**************************************************************/
  114. /* fonctions de lecture/ecriture d'une agence dans un fichier */
  115. /**************************************************************/
  116. /* -ed-
  117. int charge_agence (char *nomfichier, struct agence *ag)
  118. voir main()
  119. */
  120. static int charge_agence (char const *nomfichier, struct agence *ag)
  121. {
  122.    FILE *pf;
  123.    size_t sz;
  124.    int status;
  125.    /* on ouvre le fichier en lecture seule */
  126.    pf = fopen (nomfichier, "r" );
  127.    if (pf == NULL)
  128.       return -1;
  129.    sz = sizeof (struct agence);
  130.    /* on lit une structure de taille sz que l'on */
  131.    /* stocke a l'adresse indiquee par ag */
  132.    if (fread (ag, sz, 1, pf) == 1)
  133.       status = 0;
  134.    else
  135.       status = -1;
  136.    fclose (pf);
  137.    return status;
  138. }
  139. /* -ed-
  140. int sauve_agence (char *nomfichier, struct agence *ag)
  141. voir main().
  142. */
  143. static int sauve_agence (char const *nomfichier, struct agence *ag)
  144. {
  145.    FILE *pf;
  146.    size_t sz;
  147.    int status;
  148.    /* on ouvre le fichier en (re)ecriture */
  149.    pf = fopen (nomfichier, "w" );
  150.    if (pf == NULL)
  151.       return -1;
  152.    sz = sizeof (struct agence);
  153.    /* on ecrit la structure de taille sz stockee */
  154.    /* a l'adresse indiquee par ag */
  155.    if (fwrite (ag, sz, 1, pf) == 1)
  156.       status = 0;
  157.    else
  158.       status = -1;
  159.    fclose (pf);
  160.    return status;
  161. }
  162. /*******************************************************/
  163. /* Diverses fonctions de recherche                     */
  164. /*******************************************************/
  165. /* le resultat est l'adresse du compte, NULL en cas de */
  166. /* non-existence du compte. Attention : le compte peut */
  167. /* etre CLOS ! */
  168. /* fonction de recherche d'un compte par son numero    */
  169. static struct compte *cherche_cpt_num (struct agence *ag, int numcpt)
  170. {
  171.    int i;
  172.    for (i = 0; i < MAX_COMPTES; i++)
  173.       if (((ag->comptes[i].etat == OUVERT) ||
  174.            (ag->comptes[i].etat == CLOS)) &&
  175.           (ag->comptes[i].numero == numcpt))
  176.          return &(ag->comptes[i]);
  177.    return 0;
  178. }
  179. /* fonction de recherche d'un compte par son titulaire */
  180. static struct compte *cherche_cpt_titu (struct agence *ag, char *titu)
  181. {
  182.    int i;
  183.    for (i = 0; i < MAX_COMPTES; i++)
  184.       if (((ag->comptes[i].etat == OUVERT) ||
  185.            (ag->comptes[i].etat == CLOS)) &&
  186.           (!strcmp (ag->comptes[i].titulaire, titu)))
  187.          return &(ag->comptes[i]);
  188.    return 0;
  189. }
  190. /* fonction de recherche d'un compte libre             */
  191. static struct compte *cherche_cpt_libre (struct agence *ag)
  192. {
  193.    int i;
  194.    for (i = 0; i < MAX_COMPTES; i++)
  195.       if (ag->comptes[i].etat == LIBRE)
  196.          return &(ag->comptes[i]);
  197.    return 0;
  198. }
  199. /*******************************************************/
  200. /* fonctions de traitement                             */
  201. /*******************************************************/
  202. /* ouverture d'un compte pour titu a la date t         */
  203. /* la fonction rend : numero de compte si tout est OK, */
  204. /* -1 si l'agence est "complete", -2 si le titulaire a */
  205. /* deja un compte                                      */
  206. static int traite_ouverture (struct agence *ag, char *titu, time_t t)
  207. {
  208.    int i;
  209.    struct compte *cpt;
  210.    /* on verifie d'abord que le titulaire n'a pas */
  211.    /* deja un compte                              */
  212.    cpt = cherche_cpt_titu (ag, titu);
  213.    if (cpt)
  214.       return -2;
  215.    cpt = cherche_cpt_libre (ag);
  216.    if (!cpt)
  217.       return -1;
  218.    /* on remplit les champs du compte cree */
  219.    cpt->numero = ag->num_prochain_compte++;
  220.    strncpy (cpt->titulaire, titu, LONG_TITU - 1);
  221.    cpt->etat = OUVERT;
  222.    cpt->solde = 0.;
  223.    /* on remplit l'operation 0 de type OUVERTURE */
  224.    cpt->ops[0].type = OUVERTURE;
  225.    cpt->ops[0].date = t;
  226.    cpt->ops[0].montant = 0.;
  227.    /* on remplit les operations suivantes avec NO_OP */
  228.    for (i = 1; i < NB_OPS; i++)
  229.       cpt->ops[i].type = NO_OP;
  230.    return cpt->numero;
  231. }
  232. /* fonction de traitement de l'operation op sur le compte */
  233. /* de numero numcpt de l'agence ag (op != OUVERTURE)      */
  234. static int traite_operation (struct agence *ag, int numcpt,
  235.                              struct operation *op)
  236. {
  237.    int i;
  238.    struct compte *cpt;
  239.    /* on cherche le compte de numero numcpt */
  240.    cpt = cherche_cpt_num (ag, numcpt);
  241.    /* test de validite : compte inexistant ou CLOS */
  242.    if ((cpt == 0) || (cpt->etat == CLOS))
  243.       return -1;
  244.    switch (op->type)
  245.    {
  246.    case DEPOT:
  247.       cpt->solde += op->montant;
  248.       ag->solde += op->montant;
  249.       break;
  250.    case RETRAIT:
  251.       if (cpt->solde < op->montant)
  252.          return -1;
  253.       cpt->solde -= op->montant;
  254.       ag->solde -= op->montant;
  255.       break;
  256.    case CLOTURE:
  257.       if (cpt->solde != 0)
  258.          return -1;
  259.       cpt->etat = CLOS;
  260.       break;
  261.    default:
  262.       return -1;
  263.    }
  264.    /* on "decale" les operations du tableau ops */
  265.    for (i = NB_OPS - 2; i >= 0; i--)
  266.       cpt->ops[i + 1] = cpt->ops[i];
  267.    cpt->ops[0] = *op;
  268.    return 0;
  269. }
  270. /* fonction d'affichage du solde de l'agence             */
  271. static void solde_agence (struct agence *ag)
  272. {
  273.    printf ("Le solde de l'agence est %.2f\n", ag->solde);
  274. }
  275. /* fonction de "purge" de l'agence : libere les comptes  */
  276. /* CLOS avant la date t */
  277. static void purge_agence (struct agence *ag, time_t t)
  278. {
  279.    int i, nb;
  280.    for (i = 0, nb = 0; i < MAX_COMPTES; i++)
  281.       /* si le compte est CLOS, et que la cloture a eu */
  282.       /* lieu avant "cur", on remet a zero le compte */
  283.       if ((ag->comptes[i].etat == CLOS) && (ag->comptes[i].ops[0].date < t))
  284.       {
  285.          printf ("Purge du compte %d\n", ag->comptes[i].numero);
  286.          raz_compte (&(ag->comptes[i]));
  287.          nb++;
  288.       }
  289.    printf ("%d comptes purges\n", nb);
  290. }
  291. /* effectue un releve de l'operation op. le format est :    */
  292. /* JJ/MM/AAAA HH:MM ouverture/cloture/[depot,retrait] de XX */
  293. /* on utilise localtime pour convertir les dates            */
  294. static void releve_operation (struct operation *op)
  295. {
  296.    struct tm *d;
  297.    if (op->type == NO_OP)
  298.       return;
  299.    d = localtime (&(op->date));
  300.    if (d == 0)
  301.       fputs ("\tXX/XX/XXXX XX:XX ", stdout);
  302.    else
  303.       printf ("\t%02d/%02d/%04d %02d:%02d ",
  304.               d->tm_mday, d->tm_mon + 1, d->tm_year + 1900,
  305.               d->tm_hour, d->tm_min);
  306.    switch (op->type)
  307.    {
  308.    case OUVERTURE:
  309.       fputs ("ouverture\n", stdout);
  310.       return;
  311.    case CLOTURE:
  312.       fputs ("cloture\n", stdout);
  313.       return;
  314.    case DEPOT:
  315.       printf ("depot de %.2f E\n", op->montant);
  316.       return;
  317.    case RETRAIT:
  318.       printf ("retrait de %.2f E\n", op->montant);
  319.       return;
  320.    }
  321. }
  322. /* fonction de releve du compte de numero numcpt           */
  323. /* on affiche les informations du compte, puis les NB_OPS  */
  324. /* (au plus) dernieres operations                          */
  325. static int releve_compte (struct agence *ag, int numcpt)
  326. {
  327.    struct compte *cpt;
  328.    int i;
  329.    cpt = cherche_cpt_num (ag, numcpt);
  330.    if (!cpt)
  331.       return -1;
  332.    printf ("Titulaire : %s\n", cpt->titulaire);
  333.    printf ("Compte %d", cpt->numero);
  334.    if (cpt->etat == CLOS)
  335.       fputs (" [CLOTURE]\n", stdout);
  336.    else
  337.       printf (", solde %.2f E\n", cpt->solde);
  338.    for (i = NB_OPS - 1; i >= 0; i--)
  339.       releve_operation (&(cpt->ops[i]));
  340.    return 0;
  341. }
  342. /*********************************************************/
  343. /* Diverses fonctions de saisie au clavier               */
  344. /* ces fonctions rendent -1 en cas d'annulation (CTRL-D  */
  345. /* frappe au clavier), sinon elles insistent indefiniment*/
  346. /* pour avoir une saisie "correcte"                      */
  347. /*********************************************************/
  348. static int saisie_num_cpt (void)
  349. {
  350.    int num;
  351.    char rep[128];
  352.    for (;;)
  353.    {
  354.       fputs ("Numero de compte" " (CTRL-D pour annuler) ? ", stdout);
  355.       if (!fgets (rep, sizeof rep, stdin))
  356.       {
  357.          /* -ed- fonction non standard. */
  358.          clearerr (stdin);
  359.          return -1;
  360.       }
  361.       fclean (rep, stdin);
  362.       if (sscanf (rep, "%d", &num) == 1)
  363.          return num;
  364.    }
  365. }
  366. static int saisie_code_op (void)
  367. {
  368.    char rep[1024];
  369.    for (;;)
  370.    {
  371.       fputs ("D(epot), R(etrait), C(loture)"
  372.              " (CTRL-D pour annuler) ? ", stdout);
  373.       if (!fgets (rep, sizeof rep, stdin))
  374.       {
  375.          clearerr (stdin);
  376.          return -1;
  377.       }
  378.       fclean (rep, stdin);
  379.       switch (rep[0])
  380.       {
  381.       case 'D':
  382.          return DEPOT;
  383.       case 'R':
  384.          return RETRAIT;
  385.       case 'C':
  386.          return CLOTURE;
  387.       default:
  388.          break;
  389.       }
  390.    }
  391. }
  392. static int saisie_titulaire (char *titu, size_t size)
  393. {
  394.    fputs ("Titulaire (CTRL-D pour annuler) ? ", stdout);
  395.    if (!fgets (titu, size, stdin))
  396.    {
  397.       clearerr (stdin);
  398.       return -1;
  399.    }
  400.    fclean (titu, stdin);
  401.    return 0;
  402. }
  403. static int saisie_montant (double *v)
  404. {
  405.    char rep[32];
  406.    for (;;)
  407.    {
  408.       fputs ("Montant" " (CTRL-D pour annuler) ? ", stdout);
  409.       if (!fgets (rep, sizeof rep, stdin))
  410.       {
  411.          clearerr (stdin);
  412.          return -1;
  413.       }
  414.       fclean (rep, stdin);
  415.       if (sscanf (rep, "%lf", v) == 1)
  416.          return 1;
  417.    }
  418. }
  419. /* fonction de saisie de date                            */
  420. /* la date est saisie sous la forme JJ/MM/AAAA HH:MM     */
  421. /* la fonction propose la date courante, si l'utilisateur*/
  422. /* ne tape rien (<Return> ou CTRL-D), on accepte cette   */
  423. /* date courante                                         */
  424. static time_t saisie_date (void)
  425. {
  426.    time_t t;
  427.    struct tm *d, buf;
  428.    char rep[32];
  429.    for (;;)
  430.    {
  431.       t = time (0);
  432.       d = localtime (&t);
  433.       fputs ("Date ", stdout);
  434.       if (d)
  435.          printf ("(%02d/%02d/%04d %02d:%02d) ? ",
  436.                  d->tm_mday, 1 + d->tm_mon, d->tm_year + 1900,
  437.                  d->tm_hour, d->tm_min);
  438.       if (!fgets (rep, sizeof rep, stdin) || (rep[0] == '\n'))
  439.       {
  440.          clearerr (stdin);
  441.          return t;
  442.       }
  443.       fclean (rep, stdin);
  444.       if (sscanf (rep, " %d/%d/%d %d:%d",
  445.                   &(buf.tm_mday), &(buf.tm_mon), &(buf.tm_year),
  446.                   &(buf.tm_hour), &(buf.tm_min)) == 5)
  447.       {
  448.          buf.tm_mon--;
  449.          buf.tm_year -= 1900;
  450.          buf.tm_sec = 0;
  451.          buf.tm_isdst = -1;
  452.          return mktime (&buf);
  453.       }
  454.    }
  455. }
  456. /*********************************************************/
  457. /* Les differents menus pour saisir les infos et traiter */
  458. /*********************************************************/
  459. static void menu_recherche (struct agence *ag)
  460. {
  461.    char titu[LONG_TITU];
  462.    struct compte *cpt;
  463.    int num;
  464.    for (;;)
  465.    {
  466.       puts ("[Comptes/Recherche de compte]" );
  467.       if (saisie_titulaire (titu, sizeof titu) == -1)
  468.          return;
  469.       cpt = cherche_cpt_titu (ag, titu);
  470.       if (cpt)
  471.       {
  472.          printf ("compte %d, titulaire %s\n", cpt->numero, cpt->titulaire);
  473.          return;
  474.       }
  475.       /* on essaie d'interpreter le titulaire */
  476.       /* comme un numero de compte            */
  477.       if (sscanf (titu, "%d", &num) == 1)
  478.       {
  479.          cpt = cherche_cpt_num (ag, num);
  480.          if (cpt)
  481.          {
  482.             printf ("compte %d, titulaire %s\n", cpt->numero, cpt->titulaire);
  483.             return;
  484.          }
  485.       }
  486.       fputs ("NON TROUVE\n", stdout);
  487.       return;
  488.    }
  489. }
  490. static void menu_saisie_op (struct agence *ag)
  491. {
  492.    struct operation op;
  493.    int num_cpt;
  494.    for (;;)
  495.    {
  496.       puts ("[Comptes/Saisie d'operation]" );
  497.       num_cpt = saisie_num_cpt ();
  498.       if (num_cpt == -1)
  499.          return;
  500.       op.type = saisie_code_op ();
  501.       if (op.type == -1)
  502.          return;
  503.       if (op.type != CLOTURE)
  504.          if (saisie_montant (&(op.montant)) == -1)
  505.             return;
  506.       op.date = saisie_date ();
  507.       if (traite_operation (ag, num_cpt, &op) == -1)
  508.          printf ("Echec du traitement !\n" );
  509.       else
  510.          printf ("Traitement effectue !\n" );
  511.       return;
  512.    }
  513. }
  514. static void menu_releve (struct agence *ag)
  515. {
  516.    int num_cpt;
  517.    for (;;)
  518.    {
  519.       puts ("[Comptes/Releve de compte]" );
  520.       num_cpt = saisie_num_cpt ();
  521.       if (num_cpt == -1)
  522.          return;
  523.       if (releve_compte (ag, num_cpt) == -1)
  524.          fputs ("COMPTE INEXISTANT\n", stdout);
  525.       return;
  526.    }
  527. }
  528. static void menu_ouverture (struct agence *ag)
  529. {
  530.    char titu[LONG_TITU];
  531.    int num;
  532.    time_t t;
  533.    for (;;)
  534.    {
  535.       puts ("[Comptes/Ouverture]" );
  536.       if (saisie_titulaire (titu, sizeof titu) == -1)
  537.          return;
  538.       t = saisie_date ();
  539.       switch (num = traite_ouverture (ag, titu, t))
  540.       {
  541.       case -2:
  542.          puts ("CE TITULAIRE A DEJA UN COMPTE" );
  543.          return;
  544.       case -1:
  545.          puts ("L'AGENCE EST COMPLETE" );
  546.          return;
  547.       default:
  548.          printf ("compte %d cree\n", num);
  549.          return;
  550.       }
  551.    }
  552. }
  553. static void menu_purge (struct agence *ag)
  554. {
  555.    time_t tpurge;
  556.    char dummy[4];
  557.    puts ("[ATTENTION : purge des comptes (CTRL-D pour annuler)]" );
  558.    if (!fgets (dummy, sizeof dummy, stdin))
  559.    {
  560.       clearerr (stdin);
  561.       return;
  562.    }
  563.    fclean (dummy, stdin);
  564.    tpurge = saisie_date ();
  565.    purge_agence (ag, tpurge);
  566. }
  567. static void menu_comptes (struct agence *ag)
  568. {
  569.    char rep[4];
  570.    int choix;
  571.    for (;;)
  572.    {
  573.       puts ("[Comptes]" );
  574.       puts ("(1) recherche d'un numero de compte" );
  575.       puts ("(2) saisie d'une operation" );
  576.       puts ("(3) releve de compte" );
  577.       puts ("(4) ouverture de compte" );
  578.       puts ("(0) sortie" );
  579.       fputs ("--> ", stdout);
  580.       if (!fgets (rep, 1024, stdin))
  581.       {
  582.          clearerr (stdin);
  583.          return;
  584.       }
  585.       fclean (rep, stdin);
  586.       if (sscanf (rep, "%d", &choix) != 1)
  587.          continue;
  588.       switch (choix)
  589.       {
  590.       case 0:
  591.          return;
  592.       case 1:
  593.          menu_recherche (ag);
  594.          break;
  595.       case 2:
  596.          menu_saisie_op (ag);
  597.          break;
  598.       case 3:
  599.          menu_releve (ag);
  600.          break;
  601.       case 4:
  602.          menu_ouverture (ag);
  603.          break;
  604.       default:
  605.          printf ("Mauvais choix %s !\n", rep);
  606.          break;
  607.       }
  608.    }
  609. }
  610. static void menu_principal (struct agence *ag)
  611. {
  612.    char rep[4];
  613.    int choix;
  614.    for (;;)
  615.    {
  616.       puts ("(1) consultation du solde agence" );
  617.       puts ("(2) acces au menu 'comptes'" );
  618.       puts ("(3) purge des comptes" );
  619.       puts ("(4) SORTIE IMMEDIATE SANS SAUVEGARDE" );
  620.       puts ("(5) remise a zero de l'agence" );
  621.       printf ("(0) sortie\n--> " );
  622.       if (!fgets (rep, sizeof rep, stdin))
  623.       {
  624.          clearerr (stdin);
  625.          continue;
  626.       }
  627.       fclean (rep, stdin);
  628.       if (sscanf (rep, "%d", &choix) != 1)
  629.          continue;
  630.       switch (choix)
  631.       {
  632.       case 0:
  633.          return;
  634.       case 1:
  635.          solde_agence (ag);
  636.          break;
  637.       case 2:
  638.          menu_comptes (ag);
  639.          break;
  640.       case 3:
  641.          menu_purge (ag);
  642.          break;
  643.       case 4:
  644.          exit (1);
  645.           /*NOTREACHED*/ return;
  646.       case 5:
  647.          raz_agence (ag);
  648.          break;
  649.       default:
  650.          break;
  651.       }
  652.    }
  653.    return;
  654. }
  655. int main (int argc, char *argv[])
  656. {
  657. /* -ed-
  658. char *fic_agence;
  659. attention, une chaine litterale n'est pas modifiable.
  660. Il est preferable de qualifier en const (lecture seule).
  661. */
  662.    char const *fic_agence;
  663.    struct agence ag;
  664.    if (argc == 1)
  665.       fic_agence = "agence.dat";
  666.    else
  667.       fic_agence = argv[1];
  668.    if (charge_agence (fic_agence, &ag) == -1)
  669.    {
  670.       char rep[4];
  671.       perror (fic_agence);
  672.       printf ("Initialise une agence vide (o/n) ?\n" );
  673.       if (fgets (rep, sizeof rep, stdin) == NULL)
  674.       {
  675.          perror ("stdin" );
  676.          fprintf (stderr, "STOP !!!\n" );
  677.          return 2;
  678.       }
  679.       fclean (rep, stdin);
  680.       if (rep[0] == 'o' || rep[0] == 'O' || rep[0] == 'y' || rep[0] == 'Y')
  681.          raz_agence (&ag);
  682.       else
  683.       {
  684.          fprintf (stderr, "STOP !!!\n" );
  685.          return 2;
  686.       }
  687.    }
  688.    menu_principal (&ag);
  689.    if (sauve_agence (fic_agence, &ag) == -1)
  690.    {
  691.       perror (fic_agence);
  692.       return 1;
  693.    }
  694.    return 0;
  695. }


Au fait, pas une ligne sur ton histoire de mot de passe. De plus, c'est pas très clair. il y a déjà unproblème de spec. En effet, Un mot de passe 'cient' n'a de sens que si le client consulte son compte. Or
d'une part, l'ergonomie est pas organisée en 'client/action', mais en action/client ce qui veut dire demander le numéro de lient à cjhaque opération.
 
Si il s'agit d'ajouter une fonction 'consultation par le client, il faut imaginer une succession d'écrans comme ceci :  


Mon compte
-----------
 
- Compte existant
Nom :  
Mot de passe :  
 
- Nouveau compte
Nom :  
Mot de passe :  
Confirmation mot de passe :  
 
Opérations
----------
- Consultation
- Impression solde
- Impression relevé
- Quitter


quelque chose comme ça.
 
C'est à dire totalement autre chose (une autre application en faite) mais qui travaille sur le même fichier que celui de la banque.
 
C'est une application de gestion classique...


Message édité par -ed- le 04-12-2006 à 21:03:05

---------------
Emmanuel Delahaye
Des infos sur la programmation et le langage C:
http://bien-programmer.blogspot.com/  
http://mapage.noos.fr/emdel/
n°17987
cmoila
Profil : Membre
Posté le 05-12-2006 à 20:52:04  profilanswer