un peu d'aide

un peu d'aide - C - Programmation

Marsh Posté le 27-11-2005 à 19:55:03    

Salut à tous
 
Voilà j'ai un petit projet à faire et je suis bloqué à un endroit...
J'arrive pas à écrire correctement dans mon fichier et forcement je lis un peu n'importe quoi...
 
je poste donc mon code avec un petit main de test histoire de et puis donc c'est les fonctions ecriture et lecture:
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <conio.h>
 
 
typedef struct maillon
{
    char nom[20];    
    int  temps;
    struct maillon *suiv ;
} T_maillon ;
 
/******************************************************************************
Fonction Création de maillon
Description : La fonction va insérer un nouveau maillon en début de liste
qu'elle soit vide ou non.
******************************************************************************/
int Ajoutermaillonscore (T_maillon **p, int tps_ecoule)
{
   T_maillon *nouveau=NULL,*precedent=NULL,*courant=*p;
   
   nouveau=(T_maillon *)malloc(sizeof (T_maillon));
   printf("Entrez votre nom:\n" );
   scanf("%s",&nouveau->nom);
   
   nouveau->temps=tps_ecoule;
   printf("Le temps ecoule est:%d\n",nouveau->temps);  
   
   if(nouveau==NULL)
      printf("\nErreur d'allocation mémoire\n\n" );
   
   else
   {
     nouveau->suiv=NULL;
     if(courant==NULL)
        *p=nouveau;                       // Insertion en début de liste vide
     else
     {
          if(precedent==NULL)
         {
          nouveau->suiv=*p;
          *p=nouveau;       // insertion en début de liste non vide
         }
    }
   }  
}
/******************************************************************************
Fonction Trier par temps
Description : La fonction va trier les maillons par temps
******************************************************************************/
void trierpartemps(T_maillon **tete)
{
 int modif=0;
 T_maillon * precedent=NULL, *courant=NULL, *suivant=NULL;
 precedent=courant=suivant=*tete;
 
 suivant=courant->suiv;
 
 if(*tete==NULL)
  printf("La liste est vide\n" );
 else
 {
  do
  {
   modif=0;
   precedent=courant=*tete;
   suivant=courant->suiv;
   
   while(suivant!=NULL)
   {
    if(((courant->temps)>(suivant->temps))&&(courant==*tete))
    { /*Inversion du 1er et 2nd maillon */
     courant->suiv=suivant->suiv;
     suivant->suiv=courant;
     *tete=suivant;
     modif=100;
     courant=*tete;
     suivant=courant->suiv;
    }
     
    if((courant->temps)>(suivant->temps))
    { /* Inversion de 2 maillons consécutifs */
     courant->suiv=suivant->suiv;
     suivant->suiv=courant;
     precedent->suiv=suivant;
     modif=100;
     courant=precedent->suiv;
     suivant=courant->suiv;
    }
 
    precedent=courant;
    courant=suivant;
    suivant=suivant->suiv;
   }
  }
  while(modif!=0);
   }  
}
/******************************************************************************
Fonction d'affichage
Description : Cette fonction va permettre l'affichage d'une liste chainée sous  
la forme d'un tableau ( Simple effet visuel!!)
******************************************************************************/
 
void Afficherliste(T_maillon *courant)
{
     int cpt=0 ;
     
        printf("\n\t\t-------AFFICHAGE DE LA LISTE----------\n\n" );
         
        if(courant==NULL)
        printf("La liste est vide\n" );
       
        else
        {
            printf("Voici le classement:\n" );
            while(courant!=NULL)
            {
       printf("%s\t\t",courant->nom);
    printf("%d sec\n",courant->temps);
               courant=courant->suiv;  
            }
        }
}  
 
/******************************************************************************
Fonction Ecriture dans un fichier
Description : Cette fonction crée un fichier, l'ouvre en écriture et vient sauvegarder
la partie en cours dans un fichier dont on choisit le nom.
******************************************************************************/
 
int Ecriturefichierscore (T_maillon *courant)
{
    char *nom_fic=NULL;
    FILE *f=NULL;
    int cpt1=0,cpt2=0,cpt3=0;
     
    //courant=(T_maillon *)malloc(sizeof(T_maillon));
    nom_fic= (char *)malloc(sizeof(char)*30); // Pas plus de 30 caractères pour le nom
     
    if(nom_fic==NULL || courant==NULL)
       printf("\nErreur d'allocation mémoire\n\n" );
       
       else
       {
           printf("\n\t\t-------SAUVEGARDE DANS UN FICHIER----------\n\n" );
         
           printf("Entrez le nom du fichier: " );
           scanf("%s",nom_fic);
           strcat(nom_fic,".txt" );
         
           f=fopen(nom_fic,"w+" );
           fseek(f,0,SEEK_SET);
         
           while(courant!=NULL)
           {
            cpt1++;
            cpt2=cpt2+fwrite(courant,sizeof(T_maillon),1,f);
            courant=courant->suiv;
           }
             if(f!=NULL)
             fclose(f);
         
              if (cpt1==cpt2)
                  return -1;
                       
                 else
                  return 1;  
       }
}
 
/******************************************************************************
Fonction de lecture dans le fichier
Description : Cette fonction va permettre la restauration d'une partie au préalable
enregistrée à l'aide du nom de fichier
******************************************************************************/
void lecturefichierscore(T_maillon *p)
{
     char *nom_fic=NULL;
    FILE *f=NULL;
    T_maillon *courant;
 
    courant=(T_maillon *)malloc(sizeof(T_maillon));
    nom_fic= (char *)malloc(sizeof(char)*30); // Pas plus de 30 caractères pour le nom
 
    if(nom_fic==NULL || courant==NULL)
       printf("\nErreur d'allocation mémoire\n\n" );
    else
    {
        printf("\n\t\t-------LECTURE D UN FICHIER----------\n\n" );  
        printf("Entrez le nom du fichier: " );
        scanf("%s",nom_fic);
        strcat(nom_fic,".txt" );
         
        f=fopen(nom_fic,"r+" );
        if (f==NULL)
        printf("Le fichier n'existe pas!!!\n" );
         
  else
        {
   printf("Voici le classement:\n" );
            fseek(f,0,SEEK_SET);
            while(fread(courant,sizeof(T_maillon),1,f)!=0)
            fprintf(stdout,"%s\t\t",courant->nom);
   fprintf(stdout,"%d sec\n",courant->temps);
            courant=courant->suiv;
        }
    }
}
int main()
{
 
 T_maillon *tete = NULL ;
  Ajoutermaillonscore (&tete,50) ;
  Ajoutermaillonscore (&tete,30) ;
  Ajoutermaillonscore (&tete,15) ;
  Ajoutermaillonscore (&tete,120) ;
  Ajoutermaillonscore (&tete,59) ;
 
  trierpartemps(&tete);
  Afficherliste(tete);
 
  Ecriturefichierscore (tete);
  lecturefichierscore(tete);
    system ("pause" );  
 
}
 
 
J'espère que qq un pourra m'aider...  
je vous remercie par avance... et puis pour ce qui ont vraiment envie de m'aider j'ai un autre petit pb sur de l'algo que j'arrive pas à regler...lol
 
@+

Reply

Marsh Posté le 27-11-2005 à 19:55:03   

Reply

Marsh Posté le 27-11-2005 à 20:19:24    

Citation :

typedef struct maillon  
{  
    char nom[20];    
    int  temps;  
    struct maillon *suiv ;  
} T_maillon ;  
...
           f=fopen(nom_fic,"w+" );  
...
            cpt2=cpt2+fwrite(courant,sizeof(T_maillon),1,f);


Il manque une lettre "b" minuscule pour indiquer que le fichier doit être ouvert en mode binaire et non pas en mode texte. Faire :

...
           f=fopen(nom_fic,"w+b" );  
...


Deux petites remarques complémentaires :
 
1. Quand de la mémoire est allouée avec malloc(), il faut la libérer avec free().
 
2. Il est préférable d'allouer des données locales sur la pile que de les allouer sur le tas avec une fonction d'allocation mémoire. L'appel à la fonction malloc() doit réalisé à bon escient et avec parcimonie.

Reply

Marsh Posté le 27-11-2005 à 20:25:36    

euh... ça marche pas qd mm... désolé de te decevoir

Reply

Marsh Posté le 27-11-2005 à 20:39:25    

bogus83 a écrit :


typedef struct maillon
{
    char nom[20];    
    int  temps;
    struct maillon *suiv ;
} T_maillon ;
 
 
/******************************************************************************
Fonction Ecriture dans un fichier
Description : Cette fonction crée un fichier, l'ouvre en écriture et vient sauvegarder
la partie en cours dans un fichier dont on choisit le nom.
******************************************************************************/
 
int Ecriturefichierscore (T_maillon *courant)
{
    char *nom_fic=NULL;
    FILE *f=NULL;
    int cpt1=0,cpt2=0,cpt3=0;
     
    //courant=(T_maillon *)malloc(sizeof(T_maillon));
    nom_fic= (char *)malloc(sizeof(char)*30); // Pas plus de 30 caractères pour le nom
     
    if(nom_fic==NULL || courant==NULL)
       printf("\nErreur d'allocation mémoire\n\n" );
       
       else
       {
           printf("\n\t\t-------SAUVEGARDE DANS UN FICHIER----------\n\n" );
         
           printf("Entrez le nom du fichier: " );
           scanf("%s",nom_fic);
           strcat(nom_fic,".txt" );
         
           f=fopen(nom_fic,"w+" );
           fseek(f,0,SEEK_SET);
         
           while(courant!=NULL)
           {
            cpt1++;
            cpt2=cpt2+fwrite(courant,sizeof(T_maillon),1,f);
            courant=courant->suiv;
           }
             if(f!=NULL)
             fclose(f);
         
              if (cpt1==cpt2)
                  return -1;
                       
                 else
                  return 1;  
       }
}
 



 
1) quand on fait un malloc, ça veut dire qu'on ne connait pas à l'avance la taille nécessaire et qu'elle est calculée/saisie durant l'exécution. Tu alloues 30 octets pour le nom donc autant déclarer directement "char nom_fic[30]" (attention, 30 octets alloués mais un réservé pour le '\0' donc seulement 29 utilisables)
 
2) ouverture "w+" inutile si c'est que pour écrire
 
3) ouverture "wb" si tu es sous Zindoz
 
4) "fwrite(courant,sizeof(T_maillon),1,f)" => tu écris dans ton fichier toute ta structure en "vrac", y compris l'adresse "suiv" ce qui n'a aucun sens puisqu'une adresse dépend de l'exécution de ton programme. Lors de la relecture, ce n'est pas parce que tu liras l'adresse stockée dans le fichier que cette adresse correspondra à une zone réelement allouée
De plus, tu sais pas comment ta structure a été optimisée en interne. Certains optimiseurs de code incluent des octets pour aligner la taille de la structure sur un mot afin de gagner en rapidité. Tout ça pour dire que rien ne garantit, lors de la relecture, que les octets lus se réalignent comme il faut.
La bonne procédure est d'écrire dans ton fichier chaque membre de ta structure un après l'autre... et faire de même pour la lecture. Et chaque élément lu doit donner lieu à une insertion dans ta liste via fonction "Ajouter"
 
Et inutile de faire un "fseek" pour te positionner au début du fichier car tout "fopen" en mode "r" ou "w" te positionne d'office au début du fichier.


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 27-11-2005 à 21:14:26    

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <conio.h>
 
 
typedef struct maillon
{
    char nom[20];    
    int  temps;
    struct maillon *suiv ;
} T_maillon ;
 
/******************************************************************************
Fonction Création de maillon
Description : La fonction va insérer un nouveau maillon en début de liste
qu'elle soit vide ou non.
******************************************************************************/
int Ajoutermaillonscore (T_maillon **p, int tps_ecoule)
{
   T_maillon *nouveau=NULL,*precedent=NULL,*courant=*p;
   
   nouveau=(T_maillon *)malloc(sizeof (T_maillon));
   printf("Entrez votre nom:\n" );
   scanf("%s",&nouveau->nom);
   
   nouveau->temps=tps_ecoule;
   printf("Le temps ecoule est:%d\n",nouveau->temps);  
   
   if(nouveau==NULL)
      printf("\nErreur d'allocation mémoire\n\n" );
   
   else
   {
     nouveau->suiv=NULL;
     if(courant==NULL)
        *p=nouveau;                       // Insertion en début de liste vide
     else
     {
          if(precedent==NULL)
         {
          nouveau->suiv=*p;
          *p=nouveau;       // insertion en début de liste non vide
         }
    }
   }  
}
/******************************************************************************
Fonction Trier par temps
Description : La fonction va trier les maillons par temps
******************************************************************************/
void trierpartemps(T_maillon **tete)
{
 int modif=0;
 T_maillon * precedent=NULL, *courant=NULL, *suivant=NULL;
 precedent=courant=suivant=*tete;
 
 suivant=courant->suiv;
 
 if(*tete==NULL)
  printf("La liste est vide\n" );
 else
 {
  do
  {
   modif=0;
   precedent=courant=*tete;
   suivant=courant->suiv;
   
   while(suivant!=NULL)
   {
    if(((courant->temps)>(suivant->temps))&&(courant==*tete))
    { /*Inversion du 1er et 2nd maillon */
     courant->suiv=suivant->suiv;
     suivant->suiv=courant;
     *tete=suivant;
     modif=100;
     courant=*tete;
     suivant=courant->suiv;
    }
     
    if((courant->temps)>(suivant->temps))
    { /* Inversion de 2 maillons consécutifs */
     courant->suiv=suivant->suiv;
     suivant->suiv=courant;
     precedent->suiv=suivant;
     modif=100;
     courant=precedent->suiv;
     suivant=courant->suiv;
    }
 
    precedent=courant;
    courant=suivant;
    suivant=suivant->suiv;
   }
  }
  while(modif!=0);
   }  
}
/******************************************************************************
Fonction d'affichage
Description : Cette fonction va permettre l'affichage d'une liste chainée sous  
la forme d'un tableau ( Simple effet visuel!!)
******************************************************************************/
 
void Afficherliste(T_maillon *courant)
{
     int cpt=0 ;
     
        printf("\n\t\t-------AFFICHAGE DE LA LISTE----------\n\n" );
         
        if(courant==NULL)
        printf("La liste est vide\n" );
       
        else
        {
            printf("Voici le classement:\n" );
            while(courant!=NULL)
            {
       printf("%s\t\t",courant->nom);
    printf("%d sec\n",courant->temps);
               courant=courant->suiv;  
            }
        }
}  
 
/******************************************************************************
Fonction Ecriture dans un fichier
Description : Cette fonction crée un fichier, l'ouvre en écriture et vient sauvegarder
la partie en cours dans un fichier dont on choisit le nom.
******************************************************************************/
 
int Ecriturefichierscore (T_maillon *courant)
{
    char *nom_fic[20];
    FILE *f=NULL;
    int cpt1=0,cpt2=0,cpt3=0;
     
    //courant=(T_maillon *)malloc(sizeof(T_maillon));
 
     
    if(nom_fic==NULL || courant==NULL)
       printf("\nErreur d'allocation mémoire\n\n" );
       
       else
       {
           printf("\n\t\t-------SAUVEGARDE DANS UN FICHIER----------\n\n" );
         
           printf("Entrez le nom du fichier: " );
           scanf("%s",nom_fic);
           //strcat(nom_fic,".txt" );
         
           f=fopen(nom_fic,"wb" );
         
           while(courant!=NULL)
           {
            cpt1++;
            cpt2=cpt2+fwrite(courant->nom,sizeof(courant->nom),1,f);
   cpt3=cpt3+fwrite(courant->temps,sizeof(courant->temps),1,f);
            courant=courant->suiv;
           }
             if(f!=NULL)
             fclose(f);
         
              if (cpt1==cpt2==cpt3)
                  return -1;
                       
                 else
                  return 1;  
       }
}
 
/******************************************************************************
Fonction de lecture dans le fichier
Description : Cette fonction va permettre la restauration d'une partie au préalable
enregistrée à l'aide du nom de fichier
******************************************************************************/
void lecturefichierscore(T_maillon *p)
{
     char *nom_fic=NULL;
    FILE *f=NULL;
    T_maillon *courant,*nouveau=NULL;
 
    courant=(T_maillon *)malloc(sizeof(T_maillon));
    nom_fic= (char *)malloc(sizeof(char)*30); // Pas plus de 30 caractères pour le nom
 
    if(nom_fic==NULL || courant==NULL)
       printf("\nErreur d'allocation mémoire\n\n" );
    else
    {
        printf("\n\t\t-------LECTURE D UN FICHIER----------\n\n" );  
        printf("Entrez le nom du fichier: " );
        scanf("%s",nom_fic);
        //strcat(nom_fic,".txt" );
         
        f=fopen(nom_fic,"rb" );
        if (f==NULL)
        printf("Le fichier n'existe pas!!!\n" );
         
  else
        {
   printf("Voici le classement:\n" );
            //fseek(f,0,SEEK_SET);
            while(fread(courant,sizeof(T_maillon),1,f)!=0)
            nouveau->suiv=NULL;
   Ajoutermaillonscore(&courant,courant->temps);
   //fprintf(stdout,"%s\t\t",courant->nom);
   //fprintf(stdout,"%d sec\n",courant->temps);
            nouveau=(T_maillon *)malloc(sizeof(T_maillon));
        }
    }
}
int main()
{
 
 T_maillon *tete = NULL ;
  Ajoutermaillonscore (&tete,50) ;
  Ajoutermaillonscore (&tete,30) ;
  Ajoutermaillonscore (&tete,15) ;
  Ajoutermaillonscore (&tete,120) ;
  Ajoutermaillonscore (&tete,59) ;
 
  trierpartemps(&tete);
  Afficherliste(tete);
 
  Ecriturefichierscore (tete);
  lecturefichierscore(tete);
    system ("pause" );  
 
}
/*int main(void)  
{  
time_t deb, fin;  
 
 
 
time(&deb);  
 
 
 
 
time(&fin);  
 
printf("Il s'est ecoule entre le début et la fin %lu secondes\n", fin - deb);
system ("pause" );  
}
*/
 
 
************************************************************************************
 
Je te remercie pour tes infos mais j'ai du mal à comprendre comment je fais pour ecrire ou pour lire chaque champ de ma structure...
 
je t'ai remis le code changé ça compile mais j'ai des warning sur le fopen et le fwrite... du coup ça plante à l'éxécution...
 
Désolé mais le C c'est vraiment pas ma spécialité... je suis nul merci encore pour l'aide
 

Reply

Marsh Posté le 27-11-2005 à 21:28:12    

1) "char *nom_fic[20]" pas bon => soit tu déclares un pointeur "char *nom_fic" puis tu alloues une zone mémoire que tu relies à ce pointeur "nom_fic=malloc(...)"; soit tu alloues un tableau d'octets => "char nom_fic[20]".  
 

bogus83 a écrit :

Je te remercie pour tes infos mais j'ai du mal à comprendre comment je fais pour ecrire ou pour lire chaque champ de ma structure...


 
Ben tu fais un fwrite par membre, comme tu l'as fait ici: "cpt3=cpt3+fwrite(courant->temps,sizeof(courant->temps),1,f);"
L'idée est là... mais la fonction "fwrite" doit recevoir l'adresse de la variable à écrire. Donc => "cpt3=cpt3+fwrite(&courant->temps,sizeof(courant->temps),1,f);"
 

bogus83 a écrit :

Désolé mais le C c'est vraiment pas ma spécialité... je suis nul merci encore pour l'aide


Tout s'apprend. Evidemment si on aime le C, ca va plus vite que si on l'aime pas...
http://fr.lang.free.fr/cours/Langa [...] e_v2.0.pdf
 
 
 
 


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 27-11-2005 à 21:35:42    

Merci pour le lien mais j'en ai des classeurs plein des cours de C...
GEII + ecole d'inge + mastere.... le pb c'est que je sais pas programmer... je serai plus ou moins capable de recracher mon cours sur le C mais je suis incapable de faire un code qui fonctionne je manque de logique de programmation c'est trop abstrait... mais je me soigne enfin je code je code et je code...
je vais essayer encore ce que tu m'as montrer je te dirai si ça fonctionne
 
merci

Reply

Marsh Posté le 27-11-2005 à 21:50:23    

ça va presque marcher...lol
 
je crois que j'ai un pb avec la lecture à présent je pense...
 
il aime pas trop mon nouveau->suiv = NULL;
 
void lecturefichierscore(T_maillon *p)
{
     char *nom_fic=NULL;
    FILE *f=NULL;
    T_maillon *courant,*nouveau=NULL;
 
    courant=(T_maillon *)malloc(sizeof(T_maillon));
    nom_fic= (char *)malloc(sizeof(char)*30); // Pas plus de 30 caractères pour le nom
 
    if(nom_fic==NULL || courant==NULL)
       printf("\nErreur d'allocation mémoire\n\n" );
    else
    {
        printf("\n\t\t-------LECTURE D UN FICHIER----------\n\n" );  
        printf("Entrez le nom du fichier: " );
        scanf("%s",nom_fic);
        //strcat(nom_fic,".txt" );
         
        f=fopen(nom_fic,"rb" );
        if (f==NULL)
        printf("Le fichier n'existe pas!!!\n" );
         
  else
        {
   printf("Voici le classement:\n" );
            //fseek(f,0,SEEK_SET);
            while(fread(courant,sizeof(T_maillon),1,f)!=0)
            nouveau->suiv=NULL;
   Ajoutermaillonscore(&courant,courant->temps);
   //fprintf(stdout,"%s\t\t",courant->nom);
   //fprintf(stdout,"%d sec\n",courant->temps);
            nouveau=(T_maillon *)malloc(sizeof(T_maillon));
        }
    }
}
 
 
et encore merci...

Reply

Marsh Posté le 27-11-2005 à 22:43:12    

Sve@r a écrit :


3) ouverture "wb" si tu es sous Zindoz


Rien à voir.  
 
"w" -> texte
"wb" -> binaire
 
Toujours et partout. C'est standard.
 
Se méfier de certains systèmes qui font prendre les vessies pour des lanternes...
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 28-11-2005 à 00:08:00    

bogus83 a écrit :


void lecturefichierscore(T_maillon *p)
{
      ...
      while(fread(courant,sizeof(T_maillon),1,f)!=0)




Pas bon. Tel que tu as écrit dans le fichier, tel tu dois le lire. Tu as écrit un nom et un age, tu dois lire un nom et un age et le stocker dans "courant"
 
Par ailleurs, ta fonction Ajoutemaillonscore" est mal conçue. En effet, dans ce genre d'algo, la fonction qui ajoute un maillon est censée recevoir un maillon déjà alloué (qu'il provienne d'une saisie ou d'un fichier) et l'ajouter là où il faut.
Toi, tu l'insères systématiquement en début de liste puis tu te fais ch... à tout trier => C'est dommage...
 
Bon, je te donne le code tel que je le pense (j'ai pas testé mais il me semble correct). Essaye de voir l'idée...

#include <stdio.h>  
#include <string.h>  
#include <stdlib.h>  
#include <time.h>  
#include <math.h>  
#include <conio.h>  
 
typedef struct maillon  
{  
    char nom[20];    
    int  temps;  
    struct maillon *suiv ;  
} T_maillon ;  
 
/******************************************************************************  
Fonction Ajout de maillon  
Description : La fonction va insérer le maillon qu'elle reçoit en début de liste  
qu'elle soit vide ou non.
Elle renvoie le nouveau début de liste (qui aura forcément changé)
******************************************************************************/  
T_maillon *AjouterMaillon(T_maillon *new, T_maillon *debut)  
{
  // Le suivant de l'élément ajouté pointe vers le début de la liste, quelle soit vide ou pas
  new->suiv=debut;
 
   // Dans tous les cas, on renvoie l'élement ajouté puisqu'il se met au début
   return (new);
}  
/******************************************************************************  
Fonction Trier par temps  
Description : La fonction va trier les maillons par temps  
******************************************************************************/  
void TrierParTemps(T_maillon **tete)  
{  
    // Je regarde pas cette fonction - Je présume qu'elle est correcte
   
}  
 
/******************************************************************************  
Fonction d'affichage  
Description : Cette fonction va permettre l'affichage d'une liste chainée sous  
la forme d'un tableau ( Simple effet visuel!!)  
******************************************************************************/  
void AfficherListe(T_maillon *courant)  
{    
        printf("\n\t\t-------AFFICHAGE DE LA LISTE----------\n\n" );  
         
        if(courant==NULL)
        {
            printf("La liste est vide\n" );  
            return;
        }
 
        printf("Voici le classement:\n" );  
        while(courant!=NULL)  
        {  
              printf("%s\t\t",courant->nom);  
              printf("%d sec\n",courant->temps);  
              courant=courant->suiv;    
         }  
}
 
/******************************************************************************  
Fonction Ecriture dans un fichier  
Description : Cette fonction crée un fichier, l'ouvre en écriture et vient sauvegarder  
la partie en cours dans un fichier dont on choisit le nom.  
******************************************************************************/  
int EcritureFichierScore (T_maillon *courant)  
{  
    char nom_fic[20];  
    FILE *f;  
    int cpt1=0,cpt2=0,cpt3=0;  
     
    printf("\n\t\t-------SAUVEGARDE DANS UN FICHIER----------\n\n" );  
         
    printf("Entrez le nom du fichier: " );  
    scanf("%s",nom_fic);  
    //strcat(nom_fic,".txt" );  
         
    f=fopen(nom_fic,"wb" );  
    if (f == NULL)
    {
          printf("Pb ouverture %s\n", nom_fic);
          return(0);
    }
         
    while(courant!=NULL)  
    {  
            cpt1++;  
            cpt2=cpt2+fwrite(courant->nom,sizeof(courant->nom),1,f);  
            cpt3=cpt3+fwrite(&courant->temps,sizeof(courant->temps),1,f);  
            courant=courant->suiv;  
     }  
     fclose(f);  
           
      // Ca je comprends pas à quoi ça sert donc je le laisse tel quel
      if (cpt1==cpt2==cpt3)  
          return -1;  
      else  
          return 1;  
}  
 
/******************************************************************************  
Fonction de lecture dans le fichier  
Description : Cette fonction va permettre la restauration d'une partie au préalable  
enregistrée à l'aide du nom de fichier
******************************************************************************/  
T_maillon *LectureFichierScore(T_maillon *debut)  
{  
    char nom_fic[20];  
    FILE *f;  
    T_maillon *courant;
    char nom[20];
    int temps;
 
     printf("\n\t\t-------LECTURE D UN FICHIER----------\n\n" );  
     printf("Entrez le nom du fichier: " );  
     scanf("%s",nom_fic);  
     //strcat(nom_fic,".txt" );  
         
     f=fopen(nom_fic,"rb" );  
     if (f==NULL)
     {
           printf("Impossible d'ouvrir %s !!!\n", nom_fic);  
           return(NULL);
     }
     printf("Chargement...\n" );  
     while(fread(nom,sizeof(nom),1,f)>0)
     {
           fread(&temps, sizeof(temps), 1, f);
           courant=(T_maillon *)malloc(sizeof(T_maillon));  
           if (courant==NULL)  
           {
                  free(courant);
                  printf("\nErreur d'allocation mémoire\n\n" );  
                  return(NULL);
           }
 
           strcpy(courant->nom, nom);
           courant->temps=temps;
           debut=AjouterMaillon(courant, debut);
     }
     fclose(f);
 
     return(debut);
}
 
// Programme permettant de tester la création et la sauvegarde
int main()  
{  
  T_maillon *liste= NULL ;
  T_maillon *courant;
  char nom[20];
  int temps;
 
  // Boucle de saisie infinie - Sortie si "temps" = 0
  while (1)
  {
      printf("Entrez le temps :" ); fflush(stdout);
      scanf(%d", &temps);
      if (temps == 0)
         break;
 
      printf("Entrez le nom :" ); fflush(stdout);
      scanf (nom);
 
      // Création du nouveau maillon
      courant=(T_maillon*)malloc(T_maillon));
      if (courant == NULL)
      {
          printf("Erreur allocation maillon\n" );
          return(-1);
      }
 
      // Copie des éléments saisis dans le courant
      strcpy(courant->nom, nom);
      courant->temps=temps;
      courant->suiv=NULL;
     
      // Ajout du maillon dans la liste
      liste=AjouteMaillon(courant, liste);
  }
 
  // Trier la liste  
  TrierParTemps(&liste);  
 
  // Afficher la liste
  AfficherListe(liste);  
 
  // Sauvegarder la liste
  EcritureFichierScore(liste);
}
 
// Programme permettant de tester la restauration
int main()  
{  
  T_maillon *liste= NULL ;
 
  // Charger la liste  
  liste=LectureFichierScore(liste);  
 
  // Afficher la liste
  Afficherliste(liste);  
}


 
Si t'es sous Linux, je te conseille de mettre toutes les fonctions dans un fichier "maillon.c" et de compiler en tapant "cc -c maillon.c"
Puis, tu écris le programme de création dans un fichier "creation.c" et tu compiles en tapant "cc maillon.o creation.c -o creation"
Enfin tu écris le programme de restauration dans un fichier "restauration.c" et tu compiles en tapant "cc maillon.o restauration.c -o restauration"

Message cité 1 fois
Message édité par Sve@r le 28-11-2005 à 14:08:30
Reply

Marsh Posté le 28-11-2005 à 00:08:00   

Reply

Marsh Posté le 28-11-2005 à 09:56:36    

Sve@r a écrit :


Si t'es sous Linux, je te conseille de mettre toutes les fonctions dans un fichier "maillon.c" et de compiler en tapant "cc -c maillon.c"


 
Genre sous win32 , c'est pas la même chose  :sol:

Message cité 1 fois
Message édité par Joel F le 28-11-2005 à 09:59:27
Reply

Marsh Posté le 28-11-2005 à 11:01:41    


Ben ecoute sincèrement j'ai réussi à le faire marcher
je te remercie honnetement d'avoir pris le temps de lire mon code("merdique" ) et de m'avoir depatouiller aussi rapidemment
 
sincèrement un grand merci à toi Sve@r
 
tu penses que ce serait abuser que de t'envoyer l'autre partie de mon programme où j'ai des soucis??
Je le fais et si personne répond c'est pas grave...qui tente rien n'a rien
j'ai un pb d'algo j'arrive pas à parcourir ma liste chainer comme je le souhaite...
En fait mon projet c'est de faire le démineur en C avec des listes chainées.... j'aurai préféré en statique perso  ;-)
mon soucis se situe au niveau de ma fonction jeu... dans cette partie l'utilisateur entre un numero de case, moi je veux rechercher cette case puis regarder si elle contient une mine ou pas... si oui le joueur a perdu si non je recherche toute les cases qu'il y a autour (mon alogo est super lourd à ce niveau!!) et je compte le nombre de mines que j'affiche dans la case que le joueur a choisi....
 
ça compile ça plante pas mais j'affiche jamais la valeur...
 
mon code entier fait 500lignes (moi et l'optimisation ça fait 4!!) je fais comment je poste tout ou juste les fonctions nécessaire sachant que je sais pas si vous me comprendrez (j'ai une logique bien à moi..lol)
 
voilà les fonctions sus citées:
 
/******************************************************************************
Fonction recherche d'un maillon
Description : Cette fonction a pour but de rechercher un maillon afin de savoir  
si il a une bombe ou pas
******************************************************************************/
int recherchermaillonmines(T_maillon *p, int numero_maillon)
{
 
 while (p != NULL)
 {
  if (p->numero == numero_maillon)
  {
   if (p->mines == -1)
   {
    return 0 ;
   }
   else
    return (-1) ;
  }
  else
   p = p->suiv ;
 }
}
 
/******************************************************************************
Fonction recherche d'un maillon
Description : Cette fonction a pour but de rechercher un maillon afin de donner la valeur  
du nombre de mines qu'il y a autour de lui
******************************************************************************/
int recherchermaillonautre(T_maillon *p, int num_maillon,int taille)
{
 int cpt=0,j,k,l,m;
 while (p != NULL)
 {
  if (p->numero == (num_maillon))
   if (p->mines == -1)
    printf("\n\t\tVous avez perdu!!!\n\n" );
    else
    {
      if(num_maillon==0)  
     {
       if(recherchermaillonmines(p, num_maillon+1)==0)
      cpt++;
      if(recherchermaillonmines(p, num_maillon+taille+1)==0)
      cpt++;
      if(recherchermaillonmines(p, num_maillon+taille)==0)
      cpt++;
      printf("le compteur vaut: %d\n",cpt);
      return (p+num_maillon)->mines == cpt;
     }
 
     if(num_maillon==(taille*taille)-1)
     {
      if(recherchermaillonmines(p, num_maillon-1)==0)
      cpt++;
      if(recherchermaillonmines(p, num_maillon-taille-1)==0)
      cpt++;
      if(recherchermaillonmines(p, num_maillon-taille)==0)
      cpt++;
      return (p+num_maillon)->mines == cpt;
     }  
 
 
     for(j=1;j<taille;j++)
     {
      if(num_maillon==((taille*taille)-1)-j)
      {  
       if(recherchermaillonmines(p, num_maillon-1)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon+1)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon-taille+1)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon-taille)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon-taille-1)==0)
       cpt++;
       return (p+num_maillon)->mines == cpt;
      }
     }
 
     for(k=1;k<taille;k++)
     {
      if(num_maillon==k)
      {
       if(recherchermaillonmines(p, num_maillon-1)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon+1)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon+taille+1)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon+taille)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon+taille-1)==0)
       cpt++;
       return (p+num_maillon)->mines == cpt;
      }
     }
 
     for(l=1;l<taille;l++)
     {
      if(num_maillon==((taille*taille)-1)-taille*l)
      {  
       if(recherchermaillonmines(p, num_maillon-1)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon+taille)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon-taille)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon+taille+1)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon-taille-1)==0)
       cpt++;
       return (p+num_maillon)->mines == cpt;
      }
     }
 
     for(m=1;m<taille;m++)
     {
      if(num_maillon==taille*m)
      {
       if(recherchermaillonmines(p, num_maillon+1)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon+taille)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon-taille)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon+taille+1)==0)
       cpt++;
       if(recherchermaillonmines(p, num_maillon-taille+1)==0)
       cpt++;
       return (p+num_maillon)->mines == cpt;
      }
     }
     
      if(recherchermaillonmines(p, num_maillon+1)==0)
      cpt++;
      if(recherchermaillonmines(p, num_maillon-1)==0)
      cpt++;
      if(recherchermaillonmines(p, num_maillon-taille)==0)
      cpt++;
      if(recherchermaillonmines(p, num_maillon+taille)==0)
      cpt++;
      if(recherchermaillonmines(p, num_maillon-taille+1)==0)
      cpt++;
      if(recherchermaillonmines(p, num_maillon-taille-1)==0)
      cpt++;
      if(recherchermaillonmines(p, num_maillon+taille+1)==0)
      cpt++;
      if(recherchermaillonmines(p, num_maillon+taille-1)==0)
      cpt++;
      return (p+num_maillon)->mines == cpt;  
    }
   
   return (-1) ;
 }  
 p = p->suiv ;
}
 
 
/******************************************************************************
Fonction affichage des valeurs
Description : Cette fonction va afficher la valeur de la case voulue par l'utilisateur
******************************************************************************/
int jeu (T_maillon *p,int taille)
{
 int num,cpt_nb_coup;
 
 do
 {
  printf("Entrez le numero de la case:\n" );
  scanf("%d",&num);
  recherchermaillonautre(p,num,taille);
  Afficherliste(p,taille);
 }while ((cpt_nb_coup!=(taille*taille)-bomb));
  if(cpt_nb_coup==(taille*taille)-bomb)
       printf("Vous avez Gagnez!!!\n" );
}
 
 
 
si qq un a du courage je l'en remercie par avance... promis c'est mon dernier soucis!!

Reply

Marsh Posté le 28-11-2005 à 13:59:55    

Joel F a écrit :

Genre sous win32 , c'est pas la même chose  :sol:


Non, juste genre "sous Win32 je sais pas le faire donc je peux pas expliquer comment le faire"  :D  
 

Reply

Marsh Posté le 28-11-2005 à 14:33:45    

bogus83 a écrit :

Ben ecoute sincèrement j'ai réussi à le faire marcher
je te remercie honnetement d'avoir pris le temps de lire mon code("merdique" ) et de m'avoir depatouiller aussi rapidemment
 
sincèrement un grand merci à toi Sve@r
 
tu penses que ce serait abuser que de t'envoyer l'autre partie de mon programme où j'ai des soucis??
Je le fais et si personne répond c'est pas grave...qui tente rien n'a rien
j'ai un pb d'algo j'arrive pas à parcourir ma liste chainer comme je le souhaite...
En fait mon projet c'est de faire le démineur en C avec des listes chainées.... j'aurai préféré en statique perso  ;-)
mon soucis se situe au niveau de ma fonction jeu... dans cette partie l'utilisateur entre un numero de case, moi je veux rechercher cette case puis regarder si elle contient une mine ou pas... si oui le joueur a perdu si non je recherche toute les cases qu'il y a autour (mon alogo est super lourd à ce niveau!!) et je compte le nombre de mines que j'affiche dans la case que le joueur a choisi....
 
ça compile ça plante pas mais j'affiche jamais la valeur...


 
J'ai besoin de savoir le contenu de la structure "T_maillon"
J'aimerais savoir aussi comment tu repères tes cases. Il me semble que tu identifies tes cases par un n° unique or, un démineur est un jeu en 2D donc tes cases devraient s'identifier par un couple de coordonnées (x, y) (même si on peut retrouver x et y en fonction du n° unique et de la taille du plateau)
 
Quelques conseils en vrac
1) essaye de mettre des majuscules dans tes noms de fonctions. C'est plus facile de lire "RechercherMaillonAutre" que "recherchermaillonautre"
 
2) au lieu de faire des strucutres correspondant parfaitement à la théorioe de la prog structurée, du style

fonction()
{
    if (condition1)
    {
         if (condition2)
         {
               if (conditon3)
               {
                     if (condition4)
                     {
                            // Je commence à coder mon travail - Mais je suis au bord droit de l'écran et je peux plus écrire de façon claire
                     }
                     else
                     {
                           // Je traite le cas où condition 4 pas bon
                     }
               }
               else
               {
                      // Je traite le cas où condition 3 pas bon
               }
          }
          else
          {
                  // Je traite le cas où condition 2 pas bon
          }
    }
    else
    {
           // Je traite le cas où condition 1 pas bon - Hum... il me faut remonter haut pour voir de quoi il s'agissait...
    }
}


... mais qui se révèlent à l'usage totalement illisibles; essaye de faire des blocs moins académiques mais beaucoup plus pratiques, de ce style

fonction()
{
    if (not condition1)
    {
        // Je traite l'anomalie correspondant à "condition 1"
        // Je sors de la fonction
    }
    if (not condition2)
    {
        // Je traite l'anomalie correspondant à "condition 2"
        // Je sors de la fonction
    }
    if (not condition3)
    {
        // Je traite l'anomalie correspondant à "condition 3"
        // Je sors de la fonction
    }
    if (not condition4)
    {
        // Je traite l'anomalie correspondant à "condition 2"
        // Je sors de la fonction
    }
 
    // Ici, je peux commencer à travailler utilement
    // Et j'ai toute la place qu'il me faut à l'écran pour écrire un code clair et lisible
}


 
3) quand on manipule des listes (ou des arbres), il est assez courant d'avoir 2 structures

  • une structure pour manipuler le noeud ou le maillon. Elle décrit le contenu du maillon
  • une structure pour manipuler la liste (ou l'arbre). Elle contient forcément le pointeur sur le début de la liste mais peut aussi contenir d'autres pointeurs, comme un pointeur sur le dernier élément lu, le dernier inséré, etc. Cela te facilitera grandement la tâche

Exemple

Code :
  1. // Structure qui manipule un maillon
  2. typedef struct s_maillon {
  3.     char nom[20];
  4.     int temps;
  5.     struct s_maillon *suiv;
  6. } t_maillon;
  7. // Structure qui manipule la liste
  8. typedef struct {
  9.     t_maillon *debut;
  10.     t_maillon *fin;
  11.     t_maillon *courant;
  12. } t_liste;


 
Ensuite, toutes tes fonctions recoivent un pointeur "t_liste* liste" puis manipulent "liste->debut", "liste->fin" ou "liste->courant"
 
4) ta fonction "cherchermaillonmines"
Tu l'as écrit comme s'il lui était possible de ne jamais trouver "numero_maillon" et dans ce cas tu ne lui fais rien renvoyer (donc renvoie "0" par défaut comme si elle avait trouvé).
Alors je ne sais pas si cette possibilité se réalise. Soit elle se réalise et tu dois lui faire renvoyer une valeur autre que "0" ou "-1"; soit la fonction trouve toujours le numero_maillon alors tu ne dois pas l'écrire comme si elle ne pouvait pas trouver.
Autrement dit, au lieu de faire

int recherchermaillonmines(T_maillon *p, int numero_maillon)  
{  
  while (p != NULL)  
  {  
      if (p->numero == numero_maillon)  
     {  
         if (p->mines == -1)  
            return 0 ;  
         else  
            return (-1) ;  
     }  
     else    // Le "else" est inutile puisque tous les cas "then" font sortir de la fonction
        p = p->suiv ;  
  }  
}

 
 
Si la fonction trouve toujours son numero_maillon, tu peux écrire:

int RechercherMaillonMines(T_maillon *p, int numero_maillon)  
{  
  while (p->numero != numero_maillon)
     p=p->suiv;
 
    return (p->mines == -1 ?0 :-1);  
}

 
 
Si la fonction peut ne pas trouver son numero_maillon, tu peux écrire:

int RechercherMaillonMines(T_maillon *p, int numero_maillon)  
{  
  while (p != NULL && p->numero != numero_maillon)
     p=p->suiv;
 
  if (p == NULL)
    return (1);
 
  return (p->mines == -1 ?0 :-1);  
}

 
 
Bon, le reste me semble vraiment trop horrible et compliqué à lire...


Message édité par Sve@r le 28-11-2005 à 14:53:11
Reply

Sujets relatifs:

Leave a Replay

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