Petit probléme pour une suppresion d'enregistrement

Petit probléme pour une suppresion d'enregistrement - C - Programmation

Marsh Posté le 15-10-2008 à 17:38:40    

Voila un programme que je prépare pour un pti. J'ai deux problèmes majeur(j'ai mis des ICI pour les trouver plus facilement) dedans qui m'empêche de continuer.

 

Le premier et le calcul/affichage de jeux identiques en stocks avec la fonction stock.
Le deuxième et la modification de la référence d'un jeux.
Si quelqu'un a une petite idée pour me débloquer je suis preneur.

 

Merci d'avance

 
Code :
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4.  
  5. //definition de la structure des interventions//
  6. typedef struct
  7. {
  8. int reference;
  9. char nom[30];
  10. char type[15];
  11. char age[10];
  12. int annee;
  13. float prix;
  14. char disponibilite[3];
  15. }location;
  16.  
  17. /*ajout d'un jeux*/
  18. void ajout (location l)
  19. {  
  20.        FILE *fenregistrement;
  21.        int i,n;
  22.        fenregistrement=fopen("c:\\enregistrement.txt","a" );      
  23.        printf("nombre d'ajout : " );
  24.        scanf("%d",&n);
  25.        for (i=0 ; i<n;i++)
  26.        {
  27.              printf("Reference du jeux : " );
  28.              scanf("%d",&l.reference);
  29.              printf("Nom du jeux : " );
  30.              fflush(stdin);
  31.              gets(l.nom);
  32.              printf("Type du jeux : " );
  33.              fflush(stdin);
  34.              gets(l.type);
  35.              printf("Age minimum (entrez 'aucun' si aucune restriction): " );
  36.              fflush(stdin);
  37.              gets(l.age);
  38.              printf("Annee de sortie du jeux : " );
  39.              scanf("%d",&l.annee);
  40.              printf("Prix de location du jeux : " );
  41.              scanf("%f",&l.prix);
  42.              printf("Disponibilité du jeux (oui ou non) :" );
  43.              fflush(stdin);
  44.              gets(l.disponibilite);
  45.              fwrite(&l,sizeof(l),1,fenregistrement);
  46.        }
  47.        fclose(fenregistrement);      
  48. }
  49.  
  50. /*affichage des jeu enregistrés*/
  51. void affichage (location l)
  52. {
  53.     int nombre;
  54.     char nomrech[30];
  55.     FILE *fenregistrement;
  56.     fenregistrement=fopen("c:\\enregistrement.txt","r" );
  57.     fread(&l,sizeof(l),1,fenregistrement);
  58.     printf("Ref." );
  59.     printf("  Nom\t\t\t" );
  60.     printf("Type\t\t" );
  61.     printf("Age minimum    " );
  62.     printf("Annee de sortie\t" );
  63.     printf("Prix\t" );
  64.     printf("Disponible\t" );
  65.     printf("Nombre de jeux identique en stock\n" );
  66.     printf("_______________________________________________________________________________________________________________\n" );            
  67.      while(!feof(fenregistrement))
  68.     {
  69.        
  70.        
  71.         printf("%d",l.reference);
  72.         printf("%10s",l.nom);
  73.         printf("%27s",l.type);
  74.         printf("%12s",l.age);
  75.         printf("%17d",l.annee);
  76.         printf("%14f euro",l.prix);
  77.         printf("%8s \n",l.disponibilite);
  78.         nomrech=l.nom;                                   ICI
  79.         stock(l,nomrech,&nombre);
  80.         printf("%10d",nombre);
  81.        
  82.         fread(&l,sizeof(l),1,fenregistrement);
  83.     }
  84.     fclose(fenregistrement);
  85. }    
  86.  
  87. /*suppression d'un jeux*/
  88. void suppression (location l)
  89. {
  90.       FILE *fenregistrement, *fenregistrement2;
  91.       int supp;
  92.       fenregistrement=fopen("c:\\enregistrement.txt","r" );
  93.       fenregistrement2=fopen("c:\\enregistrement2.txt","a" );
  94.       printf("Quelle jeux voulez-vous supprimer ? (entrez sa reference) \n" );
  95.       scanf("%d",&supp);
  96.       fread(&l,sizeof(l),1,fenregistrement);
  97.       while(!feof(fenregistrement))
  98.       {
  99.           if (supp!=l.reference)
  100.           {
  101.                fwrite(&l,sizeof(l),1,fenregistrement2);
  102.           }    
  103.           fread(&l,sizeof(l),1,fenregistrement);
  104.       }
  105.       fclose(fenregistrement);
  106.       fclose(fenregistrement2);
  107.       remove("c:\\enregistrement.txt" );
  108.       rename("c:\\enregistrement2.txt", "c:\\enregistrement.txt" );
  109. }
  110.  
  111. /*modification d'un jeux*/
  112. void modification(location l)
  113. {
  114.    FILE *fenregistrement;
  115.    int modif;
  116.    fenregistrement=fopen("c:\\enregistrement.txt","r" );
  117.    fread(&l,sizeof(l),1,fenregistrement);
  118.    printf("De quel jeux voulez vous changer la reference? (entrez l'ancienne reference) \n" );
  119.    scanf("%d",&modif);
  120.    while(!feof(fenregistrement))
  121.    {
  122.        if (modif==l.reference)
  123.        {
  124.            printf("la reference actuelle est : %d\n",l.reference);            ICI
  125.            printf("Par quoi voulez vous la remplacer?\n" );
  126.            scanf("%d",&l.reference);
  127.            fwrite(&l,sizeof(l),1,fenregistrement);
  128.        }
  129.        fread(&l,sizeof(l),1,fenregistrement);
  130.    }
  131.    fclose(fenregistrement);
  132. }
  133.  
  134. /*calcul du nombre de jeux en stock  */                      ICI
  135. void stock(location l,int nomrech,int *nombre)
  136. {
  137.    FILE *fenregistrement;
  138.    *nombre=0;
  139.    fenregistrement=fopen("c:\\enregistrement.txt","r" );
  140.    fread(&l,sizeof(l),1,fenregistrement);
  141.    while(!feof(fenregistrement))
  142.    {
  143.        if(strcmp(nomrech,l.nom))
  144.        {
  145.            *nombre++;
  146.        }
  147.        fread(&l,sizeof(l),1,fenregistrement);
  148.    }
  149.    fclose(fenregistrement);
  150. }  
  151.  
  152. int main()
  153. {
  154.    int menu,modif,j,nbrinter,inter,i;
  155.    location l;
  156.    menu=0;
  157.    do
  158.    {
  159.      printf("\n\nMenu\n" );
  160.      printf("1- Ajout d'un jeux\n" );
  161.      printf("2- Affichage de tous les jeux\n" );
  162.      printf("3- Supression\n" );
  163.      printf("4- Modification de la reference\n" );
  164.      printf("5- Quitter\n\n" );
  165.      printf("Entrez votre choix: " );
  166.      scanf("%d",&menu);
  167.      switch(menu)
  168.      {
  169.                 case 1 :
  170.                 ajout(l);
  171.                 break;
  172.                
  173.                 case 2:  
  174.                 affichage(l);
  175.                 break;
  176.                
  177.                 case 3 :
  178.                 suppression(l);
  179.                 break;    
  180.                
  181.                 case 4:
  182.                 modification(l);
  183.                 break;    
  184.      }
  185.      
  186.    }
  187.    while(menu!=5);
  188.    getch();
  189.    
  190. }
 


Message édité par Poupou49 le 15-10-2008 à 19:02:05

---------------
Tic !! Tac !! Boom !!  \o/ !! - "Si les hommes pensent avec leur bite, faut croire que les femmes sont drôlement handicapé en en étant privé" _Tchip_
Reply

Marsh Posté le 15-10-2008 à 17:38:40   

Reply

Marsh Posté le 15-10-2008 à 18:04:31    

Oué, pas trop mal. Quelques pistes :
 

  • La copie de chaine en C, ce n'est pas l'opérateur = mais la "fonction" strcpy().
  • Le deuxième paramètre de stock() devrait être char * pas int.


Quelques autres remarques :

  • gets c'est un peu casse gueule, utilise fgets.
  • fflush(stdin) ne fait rien du tout.
  • Edit: Vérifie les codes de retour de fopen().

Message cité 1 fois
Message édité par tpierron le 15-10-2008 à 18:05:50
Reply

Marsh Posté le 15-10-2008 à 19:01:25    

tpierron a écrit :

Oué, pas trop mal. Quelques pistes :
 

  • La copie de chaine en C, ce n'est pas l'opérateur = mais la "fonction" strcpy().
  • Le deuxième paramètre de stock() devrait être char * pas int.


j'avais pas pensé à ca merci bien je vais essayer dès que je rentre

tpierron a écrit :


Quelques autres remarques :

  • gets c'est un peu casse gueule, utilise fgets.
  • fflush(stdin) ne fait rien du tout.
  • Edit: Vérifie les codes de retour de fopen().



pour les deux premier point c'est comme ca que notre prof nous a apprit mais je vais essayer comme tu dis
et si non tu me dis que je peux pas modifier car je suis en read c'est bien çà ?
 
en tout cas merci bien pour ton aide


---------------
Tic !! Tac !! Boom !!  \o/ !! - "Si les hommes pensent avec leur bite, faut croire que les femmes sont drôlement handicapé en en étant privé" _Tchip_
Reply

Marsh Posté le 15-10-2008 à 19:53:22    


Poupou49 a écrit :


pour les deux premier point c'est comme ca que notre prof nous a apprit mais je vais essayer comme tu dis


 
 [:max evans]  
 
Ton professeur est incompétent.
1. gets() est une fonction dépréciée depuis... pfiou... 20 ans ? Plus ? Elle n'existe encore que pour conserver une compatibilité avec les très vieux programmes. Elle NE DOIT PAS être utilisée, pour une raison très simple : il est impossible de contrôler la taille de ce qui est lu avec cette fonction, donc il est impossible de sécuriser un programme niveau gestion de la mémoire. N'importe quelle manpage ("man gets" sous Unix, sinon sous Google si tu n'es pas sous Unix) le dit d'ailleurs, en voici une au hasard sur google :

SECURITY CONSIDERATIONS
 
     The gets() function cannot be used securely.  Because of its lack of
     bounds checking, and the inability for the calling program to reliably
     determine the length of the next incoming line, the use of this function
     enables malicious users to arbitrarily change a running program's func-
     tionality through a buffer overflow attack.  It is strongly suggested
     that the fgets() function be used in all cases.  (See the FSA.)


 
Un prof qui suggère l'utilisation de cette fonction doit être pendu haut et court.
 
2. fflush(stdin) a un comportement non défini par la norme.  Ce qui signifie que le comportement peut varier d'un système d'exploitation à un autre, puisqu'il n'est pas universellement défini. C'est complètement incontrôlable, il ne faut donc jamais utiliser fflush(stdin). Le plus souvent, d'ailleurs, cet appel ne fait rien du tout. Il y a une raison simple à cela : stdin, c'est un flux standard d'entrée. Habituellement c'est le clavier, mais... un simple pipe suffit à changer la donne, et du coup ça peut être n'importe quoi. Donc pas de fflush(stdin).
 
Vu ce que te recommande ton prof, achète un bouquin et potasse de ton côté, tu t'en sortiras mieux. Jette notamment un coup d'oeil sur "Le Langage C", de Kernighan&Ritchie, la référence pour ce langage. De toute façon c'est un achat utile.

Reply

Marsh Posté le 15-10-2008 à 19:54:50    

Poupou49 a écrit :


pour les deux premier point c'est comme ca que notre prof nous a apprit mais je vais essayer comme tu dis
et si non tu me dis que je peux pas modifier car je suis en read c'est bien çà ?


 
Pour la fonction "gets", ce n'est pas un drame dans un exercice comme ça. C'est juste qu'en utilisant fgets on prends conscience des problèmes de buffer overflow (très difficile à corriger en C, donc vaut mieux les éviter).
 
Pour fflush(stdin) je viens de me rendre compte que ça fonctionne sous Windows. Donc oublie la remarque.
 
Sinon d'autres trucs qui ne vont pas dans ton code :
 
Tes boucles ne sont pas tout à fait correcte. Tu fais:  
lire(enregistrement)
tant que(pas fini)
{
    imprime(enregistrement)
    lire(enregistrement)
}
 
Bah ça ne t'imprimeras jamais ton dernier enregistrement. Un truc plus mieux (et plus court) :
tant que(lire(enregistrement) > 0)
{
    imprime(enregistrement)
}
 
Aussi, spécificité Windows, tes fichiers sont binaires, donc rajoutes absolument le "b" dans le mode d'ouverture du fichier, sinon ça va coincer.

Reply

Marsh Posté le 15-10-2008 à 20:03:42    

tpierron a écrit :

Pour la fonction "gets", ce n'est pas un drame dans un exercice comme ça. C'est juste qu'en utilisant fgets on prends conscience des problèmes de buffer overflow (très difficile à corriger en C, donc vaut mieux les éviter).


 
Aucun intérêt d'enseigner une fonction dépréciée et dangereuse, quand il est tout aussi facile d'en apprendre une autre.
Tout au plus on peut l'évoquer pour expliquer pourquoi il ne faut pas l'utiliser (ce qui est marqué partout, dans les bouquins, les manpages, les aides en ligne, etc).

Reply

Marsh Posté le 15-10-2008 à 20:08:56    

Ouais, mais bon, pour un TP (très certainement sur les fichiers), que l'interface utilisateur soit pourrie, je ne pense pas que ça soit crucial dans ce contexte.
 
Bon toujours est-il que fgets(bleurp, sizeof bleurp, stdin), ce n'est pas beaucoup plus long que gets(bleurp).

Reply

Marsh Posté le 15-10-2008 à 21:40:04    

Elmoricq a écrit :


 
 
 [:max evans]  
 
Ton professeur est incompétent.
1. gets() est une fonction dépréciée depuis... pfiou... 20 ans ? Plus ? Elle n'existe encore que pour conserver une compatibilité avec les très vieux programmes. Elle NE DOIT PAS être utilisée, pour une raison très simple : il est impossible de contrôler la taille de ce qui est lu avec cette fonction, donc il est impossible de sécuriser un programme niveau gestion de la mémoire. N'importe quelle manpage ("man gets" sous Unix, sinon sous Google si tu n'es pas sous Unix) le dit d'ailleurs, en voici une au hasard sur google :

SECURITY CONSIDERATIONS
 
     The gets() function cannot be used securely.  Because of its lack of
     bounds checking, and the inability for the calling program to reliably
     determine the length of the next incoming line, the use of this function
     enables malicious users to arbitrarily change a running program's func-
     tionality through a buffer overflow attack.  It is strongly suggested
     that the fgets() function be used in all cases.  (See the FSA.)


 
Un prof qui suggère l'utilisation de cette fonction doit être pendu haut et court.
 
2. fflush(stdin) a un comportement non défini par la norme.  Ce qui signifie que le comportement peut varier d'un système d'exploitation à un autre, puisqu'il n'est pas universellement défini. C'est complètement incontrôlable, il ne faut donc jamais utiliser fflush(stdin). Le plus souvent, d'ailleurs, cet appel ne fait rien du tout. Il y a une raison simple à cela : stdin, c'est un flux standard d'entrée. Habituellement c'est le clavier, mais... un simple pipe suffit à changer la donne, et du coup ça peut être n'importe quoi. Donc pas de fflush(stdin).
 
Vu ce que te recommande ton prof, achète un bouquin et potasse de ton côté, tu t'en sortiras mieux. Jette notamment un coup d'oeil sur "Le Langage C", de Kernighan&Ritchie, la référence pour ce langage. De toute façon c'est un achat utile.


merci pour le conseil du livre et je vais utilisé fgets dorénavant.Il s'utilise comme le gets?  
 

tpierron a écrit :


 
Pour la fonction "gets", ce n'est pas un drame dans un exercice comme ça. C'est juste qu'en utilisant fgets on prends conscience des problèmes de buffer overflow (très difficile à corriger en C, donc vaut mieux les éviter).
 
Pour fflush(stdin) je viens de me rendre compte que ça fonctionne sous Windows. Donc oublie la remarque.
 
Sinon d'autres trucs qui ne vont pas dans ton code :
 
Tes boucles ne sont pas tout à fait correcte. Tu fais:  
lire(enregistrement)
tant que(pas fini)
{
    imprime(enregistrement)
    lire(enregistrement)
}
 
Bah ça ne t'imprimeras jamais ton dernier enregistrement. Un truc plus mieux (et plus court) :
tant que(lire(enregistrement) > 0)
{
    imprime(enregistrement)
}
 
Aussi, spécificité Windows, tes fichiers sont binaires, donc rajoutes absolument le "b" dans le mode d'ouverture du fichier, sinon ça va coincer.


pourtant ca marche aussi bien ma boucle je ferrais un teste avec la tienne après avoir trouvé comment tu fais lire(enregistrement)>0 ^^
 

tpierron a écrit :

Ouais, mais bon, pour un TP (très certainement sur les fichiers), que l'interface utilisateur soit pourrie, je ne pense pas que ça soit crucial dans ce contexte.
 
Bon toujours est-il que fgets(bleurp, sizeof bleurp, stdin), ce n'est pas beaucoup plus long que gets(bleurp).


je m'en fous de l'interface graphique c'est juste un PTI de fin de bts et on me demande pas d'interface utilisateur mirobolante pour çà ;)


---------------
Tic !! Tac !! Boom !!  \o/ !! - "Si les hommes pensent avec leur bite, faut croire que les femmes sont drôlement handicapé en en étant privé" _Tchip_
Reply

Marsh Posté le 16-10-2008 à 10:14:20    

donc j'ai mis des fgets partout merci bien du conseil.Mais j'ai toujours un problème pour le stock

Code :
  1. /*calcul du nombre de jeux en stock    et ICI*/
  2. void stock(location l,char nomrech,int *nombre)
  3. {
  4.    FILE *fenregistrement;
  5.    *nombre=0;
  6.    fenregistrement=fopen("c:\\enregistrement.txt","r" );
  7.    fread(&l,sizeof(l),1,fenregistrement);
  8.    while(!feof(fenregistrement))
  9.    {
  10.        if(strcmp(nomrech,l.nom)==1)
  11.        {
  12.            *nombre++;
  13.        }
  14.        fread(&l,sizeof(l),1,fenregistrement);
  15.    }
  16.    fclose(fenregistrement);
  17. }  
  18.  
  19. /*affichage des jeu enregistrés*/
  20. void affichage (location l)
  21. {
  22.     int nombre;
  23.     char nomrech[30];
  24.     FILE *fenregistrement;
  25.     fenregistrement=fopen("c:\\enregistrement.txt","r" );
  26.     fread(&l,sizeof(l),1,fenregistrement);
  27.     printf("Ref." );
  28.     printf("  Nom\t\t\t" );
  29.     printf("Type\t\t" );
  30.     printf("Age minimum    " );
  31.     printf("Annee de sortie\t" );
  32.     printf("Prix\t" );
  33.     printf("Disponible\t" );
  34.     printf("Nombre du même jeux dans le stock\n" );
  35.     printf("_______________________________________________________________________________________________________________\n" );            
  36.      while(!feof(fenregistrement))
  37.     {
  38.        
  39.        
  40.         printf("%d",l.reference);
  41.         printf("%10s",l.nom);
  42.         printf("%27s",l.type);
  43.         printf("%12s",l.age);
  44.         printf("%17d",l.annee);
  45.         printf("%14f euro",l.prix);
  46.         printf("%8s \n",l.disponibilite);
  47.         strcpy(nomrech,l.nom);
  48.         stock(l,nomrech,&nombre);
  49.         printf("%10d",nombre);
  50.        
  51.         fread(&l,sizeof(l),1,fenregistrement);
  52.     }
  53.     fclose(fenregistrement);
  54. }
 

et le code d'erreur est :
    In function `stock':
10[Warning] passing arg 1 of `strcmp' makes pointer from integer without a cast
    In function `affichage':
48 [Warning] passing arg 2 of `stock' makes integer from pointer without a cast

 

Mais je vois pas comment résoudre ce problème :s


Message édité par Poupou49 le 16-10-2008 à 10:15:42

---------------
Tic !! Tac !! Boom !!  \o/ !! - "Si les hommes pensent avec leur bite, faut croire que les femmes sont drôlement handicapé en en étant privé" _Tchip_
Reply

Marsh Posté le 16-10-2008 à 10:35:36    

nomrech est un caractère, et non un tableau de caractère, donc il est normal que strcmp() te retourne cette erreur à la compilation (puisque la fonction admet 2 tableaux de caractères en paramètres).
 
La seconde erreur est liée.
 
Il suffit simplement de modifier le prototype de ta fonction stock() (ligne 2 du code que tu donnes) pour que ça fonctionne. [:dawa]

Reply

Sujets relatifs:

Leave a Replay

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