Rechercher un mot dans un fichier et afficher son contenu en C/C++

Signaler
Messages postés
22
Date d'inscription
dimanche 29 janvier 2006
Statut
Membre
Dernière intervention
20 mars 2008
-
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
-
Bonjour,

encore moi et oui. Je suis toujours sur mn fichier de mesure. Voilà, je voudrais savoir comment on peut rechercher un mot et afficher son contenu se trouvant dans un fichier.
Exemple d'un livre:
- nom : truc
- reference : AF
- note obtenu : 12.

Mon pb est que j'utilise une structure. Ainsi, j'ai essayé de créer une fonction void nomChercher () mais cela n'a pas marcher .
J'ai donc essayé de faire ceci directement dans le main mais sans succès :

         cout << "Entrer un nom de livre pour consulter ses donnees [0 = POUR QUITTER]: ";
        cin >> nomSaisiATrouver;
     
        fgets(nomSaisiATrouver, sizeof nomSaisiATrouver, pFichier);
         fscanf(pFichier,"%s",&Mesures[n].reference) != 1;
         fscanf(pFichier,"%ld",&Mesures[n].resultat) != 1;
        
          cout << "les donnees concernant " << nomSaisiATrouver << "sont : " << endl;
       
         cout << "- Reference : " << Mesures[n].reference << endl;
         cout << "- Resultat  : " << Mesures[n].resultat  << endl;
         ++n;     

J'avais réussi à "bidouiller" pour obtenir l'intégralité des données mais cela ne fonctionnait pas bien car il n'affiche que soit une donnée ou rien. De plus, je ne sais pas encore me servir des buffers donc si vous pouvez m'aider à trouver une solution simple cela serait sympa. 

Merci.
   
      M_didi 

15 réponses

Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
Salut,
Tu devrait lire x structures et les mettres dans un buffer et ensuite tu compares le membre nom avec le nom entrée par l'utilisateur si c'est egale tu affiche les infos, sinon tu continu jusqua la fin du fichier..

Neo_Fr
Messages postés
22
Date d'inscription
dimanche 29 janvier 2006
Statut
Membre
Dernière intervention
20 mars 2008

Ok, mais comme je l'ai signalé je n'ai pas encore vu donc pas encore appris l'utilisation des buffers.  Mais, je vais de creuser ton idée en n'utilisant pas les buffers.


Merci








  
      M_didi 
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
Poste la déclaration de ta structure et je te fais un exemple si tu veux..

Neo_Fr
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
16
struct mesures

{

    char nom[20];

    char reference[15];

    long resultat;

};

mesures toto;

fread(&toto, sizeof(mesures), 1, pFichier);

Voilà. Suffit de faire fread en boucle pour tout lire. Cependant, c'est complètement impensable de faire cela dans un réel programme. Il faut passer par un buffer sinon adieu la performance.

C++ (@++)<!--
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
16
Une chose que je trouve bizarre:
fscanf(pFichier,"%s",&Mesures[n].reference) != 1;

???
C'est quoi cette ligne ?

C++ (@++)<!--
Messages postés
22
Date d'inscription
dimanche 29 janvier 2006
Statut
Membre
Dernière intervention
20 mars 2008

ok. Voici mon code



#include
#include <fstream>


using namespace std;





// --- Déclaration de la structure mesure

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




int main()
{
   try
   {
      
      //déclaration d'un tableau de Mesures de même structure que MESURE
      MESURE Mesures[1000];  
     
      //déclaration du nom de fichier qui sera créé par l'utilisateur
      char   nomFichier[256];


      //initialisation de la variable n
      int n = 0;
     
      //déclaration du pointeur sur une structure de type FILE
      FILE * pFichier;
          


      // ************************************************************
      // Création et écriture des données dans un fichier
      // ************************************************************
      cout << "\nEntrez le nom du fichier a creer : ";
      cin  >> nomFichier;


      // --- Ouverture du fichier en écriture
      pFichier = fopen(nomFichier,"wt");
     
      //teste l'ouverture du fichier
      if (pFichier == NULL) throw "Erreur d'ouverture du fichier en ecriture !";


      // --- Boucle permettant à l'utilisateur de saisir de 1 à n mesures     
      while (true)
      {
         cout << "\nSaisie de la mesure " << n + 1 << endl;


         cout << "- Nom (0=fin) : ";
         cin  >> Mesures[n].nom;
        
         //condition permettant de quitter la saisie des mesures
         if (Mesures[n].nom[0] == '0') break;
        
         cout << "- Reference   : ";
         cin  >> Mesures[n].reference;


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


         // --- Ecriture des données dans le fichier précédemment créé
         fprintf(pFichier,"%s\n",Mesures[n].nom);
         fprintf(pFichier,"%s\n",Mesures[n].reference);
         fprintf(pFichier,"%ld\n",Mesures[n].resultat);


         //incrémentation de la variable n
         ++n;
        
         //condition permettant de mettre fin automatiquement à la saisie des mesures
         if (n == 1000) break; // ouf !
      }


      // --- Fermeture du fichier
      fclose(pFichier);



   
      // ************************************************************
      //  Ouverture et écriture d'un fichier
      // ************************************************************


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


      // --- Boucle de lecture et d'affichage des mesures saisies
      cout << endl << endl << endl;
     
      //initialisation de la variable n à 0
      n = 0;
     
      //boucle permettant de lire l'intégralité du fichier
      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;        
        
      }
    


      // --- Fermeture du fichier
      fclose(pFichier);
   } // fin de try




   // --- Fonction permettant "d'attraper" les erreurs pour pouvoir les gérer ensuite
   catch (const char* erreur)
   {
      cout << erreur << endl;
      system("pause");
     
      //fin de l'exécution du programme ==> anomalie
      abort();
   }


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


J'ai essayé de mettre un peu de couleur pour faire moins triste. J'ai retiré ce que j'ai fait car sinon je crois que je me serais fais tirer les oreilles, car il y avait des trucs pas très très propres.

Merci

  
      M_didi 
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
16
fprintf(pFichier,"%s\n",Mesures[n].nom);
fprintf(pFichier,"%s\n",Mesures[n].reference);
fprintf(pFichier,"%ld\n",Mesures[n].resultat);

Pourquoi ne pas écrire d'un coup la structure dans le fichier:
fwrite(&Mesures[n], sizeof(mesures), 1, pFichier);

Tu pourras ensuite lire tout d'un coup comme j'ai montré plus haut:

fread(&Mesures[n], sizeof(mesures), 1, pFichier);

Mais je le répète, c'est impensable de faire cela dans un vrai code.

C++ (@++)<!--
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
16
A vrai dire, je ne comprend pas vraiment ton code.
        cout << "\nSaisie de la mesure " << n + 1 << endl;          cout << "- Nom (0=fin) : ";
         cin  >> Mesures[n].nom;
        
         //condition permettant de quitter la saisie des mesures
         if (Mesures[n].nom[0] == '0') break;
        
         cout << "- Reference   : ";
         cin  >> Mesures[n].reference;

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

Tu stock tes valeurs dans un tableau de structures. Cependant, à quoi sert t-il ? Tu écris immédiatement après ces même valeurs dans le fichier. Le tableau ne sert donc à rien

Tu pourrais écrire (et lire aussi) tout le tableau d'un seul coup après avoir entré toutes les valeurs non ?
(1000 ça fait beaucoup à écrire)
C++ (@++)<!--
Messages postés
22
Date d'inscription
dimanche 29 janvier 2006
Statut
Membre
Dernière intervention
20 mars 2008

Merci de vos commentaires.

Je débute en langage C/C++ donc, j'ai encore du mal faire les choses correctes. Je suis donc preneuse si il y a une optimisation possible. Au début, j'avais utiliser les ifstream et les ofstream mais sans succès.

      M_didi 
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
Un exemple ici: http://Neo_Fr.fr.nf/Book.zip

Neo_Fr
Messages postés
22
Date d'inscription
dimanche 29 janvier 2006
Statut
Membre
Dernière intervention
20 mars 2008

Merci, j'étudie ce que tu as fait

  
      M_didi 
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
16
[auteur/NEOFR/639176.aspx Neo_Fr] >> Quelque commentaires sur le code.
Ça n'aurait pas été plus simple de faire un buffer de MESURES plutôt qu'un buffer de BYTE ? Je ne vois pas l'interet du buffer de BYTE.

Ensuite:
while(1)
    {
        if(!ReadFile(hFile, Buffer, 0xFFFF0, &br, 0)) goto _Error;
        if(!br) break;

En plus structuré, ça donne ceci:

while(ReadFile(hFile, Buffer, 0xFFFF0, &br, 0) && br)
{

Pour la boucle imbriquée et la boucle dans le main:
do  while

Finalement:
if(!Buffer) { CloseHandle(hFile); return 1; }

Décale le label _Error d'une ligne vers le bas:
    HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, Buffer);
 _Error:
    CloseHandle(hFile);
    return RetVal;

puis remplace la ligne précédente par
if(!Buffer) goto _Error;

Faudra bien sur remplacer le goto _Error dans la boucle par un break ou alors par la méthode que j'ai montré plus haut.
C++ (@++)<!--
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
16
Dernière chose:

HANDLE hFile;
char szFile[MAX_PATH+4];
char szSearch[256];
MESURE Mesure;
DWORD bw, n;

Toutes ces variables globales auraient très bien pu être déclarées en locale (dans le main).

C++ (@++)<!--
Messages postés
653
Date d'inscription
mardi 6 décembre 2005
Statut
Membre
Dernière intervention
10 novembre 2014
2
Oui biensur j'aurais pu faire tout ce que tu dit plus haut...
Tout ca c'est qu'une question d'habitude..
Le principale c'est que le code fonctione et qu'il soit une minimum lisible,
apres biensur chacun sa définition de 'lisible' :D

Neo_Fr
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
16
"Tout ca c'est qu'une question d'habitude
Le principale c'est que le code fonctione"

Et bien oui si on veux mais si tu as, un jour, l'intention de prendre des cours de programmation (ou si tu en suit déjà), il faudra impérativement que tu prennes cette habitude. Aussi, rien n'est plus agréable à nos pauvres yeux qu'un code bien structuré surtout quand on n'y a pas touché depuis plusieurs semaines voir mois.

Après tout, la section entre les parenthèses du while ne sert pas à rien. ;)

C++ (@++)<!--