Lire / écrire dans un fichier avec une structure

Résolu
M_didi Messages postés 22 Date d'inscription dimanche 29 janvier 2006 Statut Membre Dernière intervention 20 mars 2008 - 18 mars 2008 à 17:20
M_didi Messages postés 22 Date d'inscription dimanche 29 janvier 2006 Statut Membre Dernière intervention 20 mars 2008 - 19 mars 2008 à 18:40
Ce que je vais faire exactement c'est créer une fonction qui me permet de créer un fichier "mesures" par le clavier et qui comporte pour chaque mesure cette structure :
- nom [20]
- reference [15]
- resultat (réel)

Ensuite, je veux créer une autre fonction qui me permet à partir du fichier créé de retrouver les informations correspondant à une mesure de nom donné

Puis, une fonction qui permet de retrouver, toujours à partir du fichier créé, les informations relatives à un rang donné (par accès direct)

Enfin, écrire un programme de test regroupant toutes ces fonctions avec possibilité de menu de choix au départ pour l'utilisateur.


Voici mon code mais cela ne marche pas. Je ne peux pas rentrer plusieurs mesures à la suite. De plus, lorsque je veux afficher ce qui a été saisie tout marche sauf le nom de la mesure. Il ne s'affiche pas.

Par ailleurs, lorsque je compile après avoir écrit "Saisie des mesures. Pour y mettre fin inserer 0.", j'ai ceci qui s'affiche juste après 0x4423c4.
Auriez-vous une idée du pourquoi? Je débute alors pardonnez-moi pour ma maladresse



#include
#include <string>
#include <fstream>

using namespace std;

// Création de la structure mesures

struct mesures
{
char nom[20];
char reference[15];
long resultat;
};


int main()

{
try
{
//création d'une mesure de même structure que mesures
mesures creationMesures[1000];

//déclaration de la variable qui comportera le nom du fichier crée par l'utilisateur
char nomFichier[20];

//initialisation de la variable n
int n = 0;

/************************************************************
Création et écriture dans un fichier
************************************************************/

cout << "\n Entrez le nom du fichier a creer : ";
cin >> nomFichier ;

//création et ouverture en écriture
ofstream fichierOut(nomFichier);

//teste l'ouverture du fichier
if(fichierOut.fail()) throw "Erreur d'ouverture de fichier en écriture ! ";

//boucle tant que permettant à l'utilisateur de saisir plusieurs mesures

do
{
cout << "Saisie des mesures. Pour y mettre fin inserer 0.";

cout << cout << "\n Saisissez le nom de la mesure : ";
cin >> creationMesures[n].nom;

cout << "\n Saisissez la reference de la mesure : ";
cin >> creationMesures[n].reference;

cout << "\n Saisissez le resultat de la mesure obtenu : ";
cin >> creationMesures[n].resultat;

if (n!=0) fichierOut << n << "\n" ; //écriture dans le fichier
}while(n);

//fermeture du fichier
fichierOut.close();

/*******************************************************************
Ouverture et écriture d'un fichier
*******************************************************************/
//ouverture en lecture
ifstream fichierIn(nomFichier);

//teste l'ouverture du fichier
if(!fichierIn.good()) throw "Erreur d'ouverture de fichier en lecture ! ";

//boucle répéter pour lire l'intégralité du fichier.
while(!fichierIn.eof())
{
if(fichierIn >> n) //fichier >> n vaudra faux quand la lecture échoue
cout << " \n Le nom de la mesure saisie est : \n" << creationMesures[n].nom << endl;
cout << " La reference de la mesure est : " << creationMesures[n].reference << endl;
cout << " Le resultat obtenu est : " << creationMesures[n].resultat << endl;
}

//fermeture du fichier
fichierIn.close();
}
//fonction permettant de gérer les erreurs
catch(char * erreur) //on "attrape les erreurs pour pouvoir les gérer
{
cout << erreur;
system ("PAUSE");
abort (); // fin exécution du programme
}
system("pause");
return 0;
}
Pour le moment j'essaye de lire et d'écrire dans le fichier. Je voudrais que cela marche avant de faire la suite.

Merci de votre aide

13 réponses

cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
19 mars 2008 à 18:30
Voilà une possibilité, avec une donnée par ligne :

#include
#include <fstream>



using namespace std;






// --- Déclaration d'une mesure
struct MESURE
{
   char nom[20];
   char reference[15];
   long resultat;
};





int main()
{
   try
   {
      MESURE Mesures[1000];   // table des mesures
      char   nomFichier[256]; // nom du fichier






      // ************************************************************
      // Saisir/Créer le fichier des mesures
      // ************************************************************
      cout << "\nEntrez le nom du fichier a creer : ";
      cin  >> nomFichier;




      // --- Ouvrir le fichier en écriture
      FILE* pFichier = fopen(nomFichier,"wt");
      if (pFichier == NULL) throw "Erreur d'ouverture du fichier en ecriture !";




      // --- Boucle de saisie/enregistrement des mesures
      int n = 0;
      while (true)
      {
         cout << "\nSaisie de la mesure " << n + 1 << endl;



         cout << "- Nom (0=fin) : ";
         cin  >> Mesures[n].nom;
         if (Mesures[n].nom[0] == '0') break; // quitter la saisie



         cout << "- Reference   : ";
         cin  >> Mesures[n].reference;



         cout << "- Resultat    : ";
         cin  >> Mesures[n].resultat;




         // --- Ecrire dans le fichier, les données sont séparées par des virgules

         fprintf(pFichier,"%s\n",Mesures[n].nom);
         fprintf(pFichier,"%s\n",Mesures[n].reference);
         fprintf(pFichier,"%ld\n",Mesures[n].resultat);




         ++n;
         if (n == 1000) break; // ouf !
      }




      // --- Fermer le fichier
      fclose(pFichier);



   
      // ************************************************************
      // Lister le fichier des mesures
      // ************************************************************




      // --- Ouvrir le fichier en lecture
      pFichier = fopen(nomFichier,"rt");
      if (pFichier == NULL) throw "Erreur d'ouverture du fichier en lecture !";




      // --- Boucle de lecture/affichage des mesures
      cout << endl << endl << endl;
      n = 0;
      while (! feof(pFichier))
      {
         if (fscanf(pFichier,"%s",&Mesures[n].nom)       != 1) break;
         if (fscanf(pFichier,"%s",&Mesures[n].reference) != 1) break;
         if (fscanf(pFichier,"%ld",&Mesures[n].resultat) != 1) break;
         cout << "\nMesure " << n + 1 << endl;
         cout << "- Nom       : " << Mesures[n].nom       << endl;
         cout << "- Reference : " << Mesures[n].reference << endl;
         cout << "- Resultat  : " << Mesures[n].resultat  << endl;
         ++n;
      }




      // --- Fermer le fichier
      fclose(pFichier);
   } // try



  
   // --- "Attraper" les erreurs pour pouvoir les gérer
   catch (const char* erreur)
   {
      cout << erreur << endl;
      system("pause");
      abort(); // fin anormale du programme
   }



  
   cout << endl;
   system("pause");
   return 0;
}


Le fichier est du genre :

mes_1
ref_1
100
mes_2
ref_2
200
mes_3
ref_3
300
mes_4
ref_4
400



Jean-François
3
M_didi Messages postés 22 Date d'inscription dimanche 29 janvier 2006 Statut Membre Dernière intervention 20 mars 2008
18 mars 2008 à 17:22
Désolé j'ai oublier de dire bonjour :euh:
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
18 mars 2008 à 19:07
        if (n!=0) fichierOut << n << "\n" ; //écriture dans le fichier

    }while(n);

Tu écris toi dans le fichier la à ton avis ?
0
cs_Arnotic Messages postés 933 Date d'inscription dimanche 1 avril 2001 Statut Membre Dernière intervention 9 janvier 2012
18 mars 2008 à 19:13
Si tu veux coller des structures dans un fichier pour les relires directes il faut déjà aligner sa structure correctement sur 4.

- reference [15] n'est pas un multiple de 4. Donc déjà ca ne va pas.

@+
Arnotic,
Admin CS,
http://dev.winsysdev.com
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
18 mars 2008 à 19:49
Voila un exemple de réalisation qui fonctionne bien :

#include
#include <fstream>



using namespace std;






// --- Déclaration d'une mesure
struct MESURE
{
   char nom[20];
   char reference[15]; // en occupera 16 (multiple de 4)
   long resultat;
};





int main()
{
   try
   {
      MESURE Mesures[1000];   // table des mesures
      char   nomFichier[256]; // nom du fichier






      // ************************************************************
      // Saisir/Créer le fichier des mesures
      // ************************************************************
      cout << "\nEntrez le nom du fichier a creer : ";
      cin  >> nomFichier;




      // --- Ouvrir le fichier en écriture

      FILE* pFichier = fopen(nomFichier,"wb");

      if (pFichier == NULL) throw "Erreur d'ouverture du fichier en ecriture !";





      // --- Boucle de saisie/enregistrement des mesures
      int n = 0;
      while (true)
      {
         cout << "\nSaisie de la mesure " << n + 1 << endl;



         cout << "- Nom (0=fin) : ";
         cin  >> Mesures[n].nom;
         if (Mesures[n].nom[0] == '0') break; // quitter la saisie



         cout << "- Reference   : ";
         cin  >> Mesures[n].reference;



         cout << "- Resultat    : ";
         cin  >> Mesures[n].resultat;




         fwrite(&Mesures[n],sizeof(MESURE),1,pFichier);
// écriture dans le fichier
         ++n;
         if (n == 1000) break; // ouf !
      }




      // --- Fermer le fichier

      fclose(pFichier);




   
      // ************************************************************
      // Lister le fichier des mesures
      // ************************************************************




      // --- Ouvrir le fichier en lecture

      pFichier = fopen(nomFichier,"rb");

      if (pFichier == NULL) throw "Erreur d'ouverture du fichier en lecture !";




      // --- Boucle de lecture/affichage des mesures
      cout << endl << endl << endl;
      n = 0;
      while (! feof(pFichier))
      {
         if (fread(&Mesures[n],sizeof(MESURE),1,pFichier) == 1)
         {
            cout << "\nMesure " << n + 1 << endl;
            cout << "- Nom       : " << Mesures[n].nom       << endl;
            cout << "- Reference : " << Mesures[n].reference << endl;
            cout << "- Resultat  : " << Mesures[n].resultat  << endl;
         }
         ++n;
      }




      // --- Fermer le fichier

      fclose(pFichier);
   } // try



  
   // --- "Attraper" les erreurs 
   catch (const char* erreur)
   {
      cout << erreur << endl;
      system("pause");
      abort(); // fin anormale du programme
   }



  
   cout << endl;
   system("pause");
   return 0;
}


Ce qui donne :

Entrez le nom du fichier a creer : c:\temp\mesures.dat



Saisie de la mesure 1
- Nom (0=fin) : mesure_1
- Reference   : reference_1
- Resultat    : 100



Saisie de la mesure 2
- Nom (0=fin) : mesure_2
- Reference   : reference_2
- Resultat    : 200



Saisie de la mesure 3
- Nom (0=fin) : mesure_3
- Reference   : reference_3
- Resultat    : 300



Saisie de la mesure 4
- Nom (0=fin) : 0





Mesure 1
- Nom       : mesure_1
- Reference : reference_1
- Resultat  : 100



Mesure 2
- Nom       : mesure_2
- Reference : reference_2
- Resultat  : 200



Mesure 3
- Nom       : mesure_3
- Reference : reference_3
- Resultat  : 300



Appuyez sur une touche pour continuer...





On peut remarquer que le tableau des mesures ne sert à rien au niveau de la saisie/enregistrement ! Une simple structure suffirait (et il n'y aurait pas la limite de 1000 à condition de faire de l'allocation dynamique à la lecture).




Jean-François
0
M_didi Messages postés 22 Date d'inscription dimanche 29 janvier 2006 Statut Membre Dernière intervention 20 mars 2008
18 mars 2008 à 20:14
Merci de m'avoir répondu.

@Arnotic : je débute en langage C/C++ , et je ne savais pas qu'il fallait un multiplie de 4. Je croyais qu'on pouvait allouer un nb de cases que l'on souhaitait sans se préoccupper des autres tableaux.

Merci jfrançois pour ton code. Je vais m'en servi pour améliorer le mien. Juste une petite question pourquoi, le nom, la référence s'enregistre bien dans le fichier mais pas le résultat ? A la place j'ai des caractères genre 3/4, { ... Enfin, c'est déjà sympa de m'avoir aidé alors faut pas faire la fine bouche car cela est rare.

Je suis désolée s'il y a des erreurs toutes bêtes mais comme je l'ai dit plus haut je débute et parfois c'est dur dur ...

  
      M_didi 
0
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
18 mars 2008 à 20:23
Le fichier est de type binaire ! les chaînes de caractères sont visibles en clair bien sûr mais pas le résultat qui est un "long". Si la mesure vaut 1 c'est le binaire 1 qui est stocké pas le caractère "1".

Jean-François
0
cs_Arnotic Messages postés 933 Date d'inscription dimanche 1 avril 2001 Statut Membre Dernière intervention 9 janvier 2012
18 mars 2008 à 20:39
Ecrire directement le code comme il le faut. Ne sert à rien d'écrire d'écrire [15] // En allou 16. Ecrire directement[16]. Servira à ne pas faire d'erreur par la suite et évite au compilo ou au système de rattraper cette betise.

@+
Arnotic,
Admin CS,
http://dev.winsysdev.com
   
   
0
M_didi Messages postés 22 Date d'inscription dimanche 29 janvier 2006 Statut Membre Dernière intervention 20 mars 2008
18 mars 2008 à 20:46
ok merci de vos explications

  
      M_didi 
0
M_didi Messages postés 22 Date d'inscription dimanche 29 janvier 2006 Statut Membre Dernière intervention 20 mars 2008
19 mars 2008 à 16:55
Bonjour, 
désolé de reposter mais lorsque j'ai voulu refaire mon code avec celui de jfrançois, c'est-à-dire le rendre compatible avec les fichiers textes et non plus binaires, et bien il m'affiche juste le nombre mesures que j'insères. Ex: 0,1,2 ... mais il n'affiche pas le reste.

Voici le code,

#include
#include <fstream>


using namespace std;


// déclaration de la structure mesure


struct MESURE
{
       char nom [20];
       char reference [16];
       long resultat;
};


int main(int argc, char *argv[])


{
    try
    {
             MESURE Mesures [1000];
             char nomFichier [256];
             FILE * fp; //déclaration du pointeur sur une structure de type FILE
             int n = 0 ; //initialisation de la variable n
            
            
             /***********************************************************
                Création et écriture dans le fichier
             ***********************************************************/
            
             cout << "\n Entrez le nom du fichier à creer : ";
             cin >> nomFichier;
            
             //création et/ou ouverture
             fp = fopen (nomFichier, "wt");
            
             //boucle tant que permettant à l'utilisateur de saisir 1 à n mesures
             while(true)
             {
                     cout << "\nSaisie de la mesure " << n + 1 << endl;


                     cout << "- Nom (0=fin) : ";
                     cin  >> Mesures[n].nom;
                     if (Mesures[n].nom[0] == '0') break; // quitter la saisie
           
                     cout << "- Reference   : ";
                     cin  >> Mesures[n].reference;
           
                     cout << "- Resultat    : ";
                     cin  >> Mesures[n].resultat;
           
                     fprintf(fp,"%d\n",n); // écriture dans le fichier
                     ++n;
                      if (n == 1000) break; // ouf !
             }
            
             //fermer le fichier
             fclose(fp);
            
            
             /********************************************************
                Ouverture et lecture du fichier
             ********************************************************/
            
             //ouverture du fichier en lecture             if ((fp fopen(nomFichier, "rt")) NULL);
            
             //boucle d'affichage et lecture des mesures
            
             cout << endl << endl << endl;
             n = 0;
             while (!feof(fp))
             {
                   if (fscanf(fp, "%d\n",&Mesures[n], sizeof(MESURE)))
                   {
                        cout << "\nMesure " << n + 1 << endl;
                        cout << "- Nom       : " << Mesures[n].nom       << endl;
                        cout << "- Reference : " << Mesures[n].reference << endl;
                        cout << "- Resultat  : " << Mesures[n].resultat  << endl;
                   }
                   ++n;
             }
            
             // fermeture du fichier
             fclose(fp);
              } // try


  
   // --- "Attraper" les erreurs
   catch (const char* erreur)
   {
      cout << erreur << endl;
      system("pause");
      abort(); // fin anormale du programme
   }


  
     cout << endl;   
    system("PAUSE");
    return EXIT_SUCCESS;
}

Comme je ne suis pas habituée avec cette méthode et très à l'aise avec les fichiers je ne sais pas ce qui ne vas pas. 
Désolé si ce sont des grosses fautes mais je débute

  
      M_didi 
0
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
19 mars 2008 à 17:45
Bonjour,
1) if ((fp fopen(nomFichier, "rt")) NULL); <-- le test ne sert à rien comme ça ! erreur ou pas on continue.

2) Pour avoir un fichier purement texte il faut écrire et lire autrement car le résultat est binaire pour l'instant. Ecrire avec des fprintf() et lire avec des fscanf() par exemple ?

Jean-François
0
M_didi Messages postés 22 Date d'inscription dimanche 29 janvier 2006 Statut Membre Dernière intervention 20 mars 2008
19 mars 2008 à 18:20
Oui mais comment on procède ?

  
      M_didi 
0
M_didi Messages postés 22 Date d'inscription dimanche 29 janvier 2006 Statut Membre Dernière intervention 20 mars 2008
19 mars 2008 à 18:40
Ok merci je vais essayer  de l'améliorer
Merci encore de m'avoir aidé

  
      M_didi 
0
Rejoignez-nous