Créer un vecteur de termes à partir d'un dossier de fichiers texte [Résolu]

Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
- - Dernière réponse : cs_mervat
Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
- 3 août 2010 à 17:31
bonjour,
pour avoir une liste contenant les termes de tous les fichiers dans un dossier, j'ai écrit ce code.
la liste que j'ai obtenue contient les termes d'un seul fichier répétés n fois (n étant le nombre de fichier dans le dossier in) alors qu'elle doit contenir les termes de tous les fichiers.
mon code me parait juste et j'ai pas pu savoir d'où la faute.
#include <dirent.h>
#include <string>
#include <vector>
#include <fstream>
#include 
// créer un vecteur de termes à partir d'un fichier texte
void fillVector(std::vector<std::string>& liste, const std::string& filename)
{
  std::ifstream entree(filename.c_str());
  std::string s;
  while (entree >> s)
  liste.push_back(s);
}

 int main()
 {
   std::vector<std::string>::iterator iter;
   std::vector<std::string>::iterator iter2;
   std::vector<std::string> liste;
   std::vector<std::string> liste2;
   static const std::string folder = "in";
   DIR* rep = opendir(folder.c_str());

if (rep)
  {  struct dirent* lecture;

  while ((lecture = readdir(rep)))
{
  fillVector (liste, lecture->d_name);
//créer un vecteur (liste2)de termes à partir d'un dossier de fichiers texte
  for (iter=liste.begin(); iter!=liste.end(); iter++)
 liste2.push_back(*iter);
 }
closedir(rep);

   }
 for (iter2=liste2.begin(); iter2!=liste2.end(); iter2++)
  std::cout << *iter2 << " ";
  std::cout<<std::endl;
  system("pause");
  return (0);
  }

Pourrais-je avoir votre aide svp?
Afficher la suite 

Votre réponse

4 réponses

Meilleure réponse
Messages postés
3830
Date d'inscription
dimanche 12 décembre 2004
Dernière intervention
19 novembre 2018
3
Merci
Plusieurs erreurs:
- La première liste contient déjà ce que tu veux, inutile de remettre une copie dans un autre vecteur. Qui plus est, tu remets des doublons dedans, car la première liste n'est pas effacé. Autant ne gardé qu'une liste.
- Tu as oublié de vérifier que le fichier en cours n'était pas "." ou ".." (Sous Linux, il faut le faire sinon ça plante).
- Vérifie bien la réussite de l'ouverture de ton fichier.

Erreurs de style:
- Inutile de déclarer 2 iter. Un seul suffit, tu aurais pu le réutiliser.
- iter++ et ++iter,; ce n'est pas pareil ! iter++ veut dire: faire une copie, incrémenter, puis réassigner (équivaut à iter = iter + 1). Alors que ++iter veut dire: ne pas faire de copie et directement assigner la valeur. ++iter est donc beaucoup beaucoup plus rapide. D'une manière générale, préfère toujours ++valeur à valeur++.
- Découpe ton code en petites fonctions. Ici, je ne te l'ai pas fait, mais tu devrais avoir une fonction qui affiche le contenu d'un vecteur, et une fonction qui remplit un vecteur en fonction d'un nom de répertoire (donc sortir le milieu du code de main dans une fonction).
Le main devrait ressembler à ça:
std::vector<std::string> liste;
getTermFromDirectory(liste, folder);
displayVector(liste);



Petite correction de ton code,
#include <dirent.h>
#include <string>
#include <vector>
#include <fstream>
#include 

// créer un vecteur de termes à partir d'un fichier texte
void fillVector(std::vector<std::string>& liste, const std::string& filename)
{
  std::ifstream entree(filename.c_str());
  if (!entree)
  {
    std::cerr << "Unable to read the file" << std::endl;
    return;
  }

  std::string s;
  while (entree >> s)
    liste.push_back(s);
}

int main()
{
  typedef std::vector<std::string>::const_iterator iter;
  static const std::string folder = "in";

  std::vector<std::string> liste;
  DIR* rep = opendir(folder.c_str());

  if (rep)
  {
    struct dirent* lecture;
    while ((lecture = readdir(rep)))
    {
      std::string filename = lecture->d_name;
      if (filename != "." && filename != "..")
fillVector (liste, folder + "/" + filename);
    }
    closedir(rep);
  }

  for (iter it = liste.begin(); it != liste.end(); ++it)
    std::cout << *it << " ";
  std::cout << std::endl;

  return (0);
}



________________________________________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 97 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cptpingu
Messages postés
3830
Date d'inscription
dimanche 12 décembre 2004
Dernière intervention
19 novembre 2018
3
Merci
Pas besoin de faire un "removeDoublon". Il y a une collection qui s'appelle le std::set qui est sert à éviter les doublons. Tu te fais une fonction qui remplit un std::set à partir d'un fichier, et tu copies l'intégralité de chacun des std::set dans un std::vector.

En gros, au lieu d'avoir: "vector + removeDoublon + vector", tu auras: set + vector.

________________________________________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 97 internautes nous ont dit merci ce mois-ci

Commenter la réponse de cptpingu
Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
0
Merci
bonjour,
merci bien pour votre aide,
en fait, j'ai fait 2 listes car je veux éliminer les doublons au sein du même fichier, donc j'ai fait une fonction removeDoublon que j'ai appelé après avoir remplis la 1ère liste, et puis je remplis la deuxième liste sans éliminer les doublons.
(i.e si un mot existe plusieurs fois dans le meme fichier ne laisser qu'une seule occurrence mais s'il existe une fois dans plusieurs fichiers garder toutes occurrences.)
si je fais une seule liste et j'exécute removeDoublon j'aurais pas le résultat voulu.
voilà la fonction removeDoublon
void removeDoublon(std::vector<std::string> & liste)
{
        bool bFound=false;
std::vector<std::string> final;
std::vector<std::string>::iterator iterListe, iterFinal;
    // Test de la validité de la liste
    if (liste.empty())
        return;
    // Init de la liste résultat
    final.push_back(*liste.begin());
    for (iterListe=liste.begin()+1; iterListe!=liste.end(); iterListe++)
    {
        // Recherche si ce n'est pas un doublon
bFound=false;
        for (iterFinal=final.begin(); iterFinal!=final.end() && !bFound; iterFinal++)
        {
            if (0==iterListe->compare(*iterFinal))
              // C'est un doublon, on passe à la chaîne suivante
                   bFound=true;
         }
        if (!bFound)
        {
            // Ce n'est pas un doublon, on l'ajoute à la liste finale
            final.push_back(*iterListe);
        }
    }
    liste=final;
}
Commenter la réponse de cs_mervat
Messages postés
90
Date d'inscription
samedi 5 juin 2010
Dernière intervention
6 mars 2015
0
Merci
c'est vrai que set permet d'éliminer les doublons donc pas besoin de removeDoublon, mais lorsque j'ai'appliqué ceci sur mon premier code avec quelques corrections j'ai obtenu la liste finale sans doublons ce qui est le contraire de ce que j'ai voulu.
Commenter la réponse de cs_mervat

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.