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

M_didi Messages postés 22 Date d'inscription dimanche 29 janvier 2006 Statut Membre Dernière intervention 20 mars 2008 - 20 mars 2008 à 17:31
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 - 20 mars 2008 à 22:14
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

Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 2
20 mars 2008 à 18:22
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
0
M_didi Messages postés 22 Date d'inscription dimanche 29 janvier 2006 Statut Membre Dernière intervention 20 mars 2008
20 mars 2008 à 18:26
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 
0
Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 2
20 mars 2008 à 18:28
Poste la déclaration de ta structure et je te fais un exemple si tu veux..

Neo_Fr
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
20 mars 2008 à 18:34
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++ (@++)<!--
0

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

Posez votre question
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
20 mars 2008 à 18:37
Une chose que je trouve bizarre:
fscanf(pFichier,"%s",&Mesures[n].reference) != 1;

???
C'est quoi cette ligne ?

C++ (@++)<!--
0
M_didi Messages postés 22 Date d'inscription dimanche 29 janvier 2006 Statut Membre Dernière intervention 20 mars 2008
20 mars 2008 à 18:41
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 
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
20 mars 2008 à 18:47
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++ (@++)<!--
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
20 mars 2008 à 18:55
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++ (@++)<!--
0
M_didi Messages postés 22 Date d'inscription dimanche 29 janvier 2006 Statut Membre Dernière intervention 20 mars 2008
20 mars 2008 à 20:12
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 
0
Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 2
20 mars 2008 à 20:18
Un exemple ici: http://Neo_Fr.fr.nf/Book.zip

Neo_Fr
0
M_didi Messages postés 22 Date d'inscription dimanche 29 janvier 2006 Statut Membre Dernière intervention 20 mars 2008
20 mars 2008 à 20:31
Merci, j'étudie ce que tu as fait

  
      M_didi 
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
20 mars 2008 à 20:58
[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++ (@++)<!--
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
20 mars 2008 à 21:01
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++ (@++)<!--
0
Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 2
20 mars 2008 à 21:48
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
0
SAKingdom Messages postés 3212 Date d'inscription lundi 7 novembre 2005 Statut Membre Dernière intervention 16 février 2009 15
20 mars 2008 à 22:14
"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++ (@++)<!--
0
Rejoignez-nous