C++ fichier+map

Résolu
velderama Messages postés 203 Statut Membre -  
mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour,
je dois lire un fichier passer en parametre puis récuperer tout les mots de plus de 3caracteres et de les enregistrer avec leur position(par rapport au début du fichier)!
Pour cela j'ai utiliser 2 classes :

-une classe main : test d'ouverture du fichier+ lancement du programme

-Et une classe CreationListe :
cree une map et ajoute les mots et leur position dans le map puis de les afficher

---------------------------------------
Classe main-->
----------------------------------------
int main(int argc , char *argv[])
{

CreationListeRef clr;
clr.remplirListe(argv[1]);
???
}
--------------------------------
Classe CreationListe.cpp-->
--------------------------------------
class CreationListe
{
public :
//la clé sera le mot et la distance la valeur du map
typedef map<char *, int> monMap;

int Getdistance() const {return dist; }//retourne la distance du mot
char* Getmot(){return mot;} //retourne le mot
void remplirListe(char *f);
void afficherListe();
CreationListeRef();

private :

int dist;
char *mot;
ifstream fichier;
};

void remplirListe(char *f){
ifstream fichier(f, ios::in);// On ouvre le fichier en lecture
????

}
void afficherListe(){
????????
}

A partir de là j'arrive plus a continuer c'est confus dans ma tete.
Ps : je suis debutant en c++ votre aide me serait essentiel.
Merci d'avance

7 réponses

  1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 943
     
    Une façon de faire :
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <map>
    #include <set>
    
    struct position_t{
        unsigned no_line;
        unsigned position;
        position_t(unsigned l,unsigned p):no_line(l),position(p){}
    };
    
    // L'opérateur < est utilisé pour pouvoir manipuler des std::set<position_t>
    inline bool operator<(
        const position_t & x,
        const position_t & y
    ){
        return x.no_line < y.no_line || (x.no_line == y.no_line && x.position < y.position);
    }
    
    // Retourne true si c est un caractère pouvant séparer deux mots
    inline bool is_delim(char c){
        return (c==' '); // on peut mettre aussi : return !isalpha(c);
    }
    
    int main(){
        const char *filename = "plop.txt";
        std::ifstream ifs("plop.txt");
        if(!ifs){
            std::cerr << "impossible d'ouvrir " << filename << std::endl;
            return 1;
        }
    
        // Lire le fichier
        std::map<std::string,std::set<position_t> > mots;
        {
            std::string line;
            for(unsigned no_line = 0;std::getline(ifs,line);++no_line){
                std::cout << "ligne = " << line << std::endl;
                unsigned beg = 0;
                unsigned end = 1;
                for(unsigned no_mot=0;end < line.size();++no_mot){
                    for(;end < line.size() && !is_delim(line[end]);++end);
                    std::string mot(line,beg,end-beg);
    
                    if(mot.size()>=3){
                        std::cout << "\tajoute le mot [" << mot << "], ligne = " 
                          << no_line << " position = " << beg  << std::endl;
                        mots[mot].insert(position_t(no_line,beg));
                    }
                    beg = end + 1;
                    end = beg + 1;
                }
    
            }
        }
        ifs.close();
    
        // Afficher les mots retenus
        {
            std::map<std::string,std::set<position_t> >::const_iterator
                mots_it (mots.begin()),
                mots_end(mots.end());
            for(;mots_it!=mots_end;++mots_it){
                const std::string & mot_cur = mots_it->first;
                const std::set<position_t> & positions = mots_it->second;
                std::cout << "mot [" << mot_cur << ']' << std::endl;
                std::set<position_t>::const_iterator
                    positions_it (positions.begin()),
                    positions_end(positions.end());
                for(;positions_it!=positions_end;++positions_it){
                    const position_t & pos_cur = *positions_it;
                    std::cout << "\tligne = " << pos_cur.no_line << " position = " 
                        << pos_cur.position << std::endl;
                }
            }
        }
        return 0;
    }
    

    Ce qui donne :
    (mando@aldur) (~) $ cat plop.txt
    Le tapir est un petit être sensible
    Il aime gambader dans la savane
    J aime beaucoup ces petits animaux
    (mando@aldur) (~) $ g++ -W -Wall plop.cpp
    (mando@aldur) (~) $ ./a.out
    ligne = Le tapir est un petit être sensible
            ajoute le mot [tapir], ligne = 0 position = 3
            ajoute le mot [est], ligne = 0 position = 9
            ajoute le mot [petit], ligne = 0 position = 16
            ajoute le mot [être], ligne = 0 position = 22
            ajoute le mot [sensible], ligne = 0 position = 28
    ligne = Il aime gambader dans la savane
            ajoute le mot [aime], ligne = 1 position = 3
            ajoute le mot [gambader], ligne = 1 position = 8
            ajoute le mot [dans], ligne = 1 position = 17
            ajoute le mot [savane], ligne = 1 position = 25
    ligne = J aime beaucoup ces petits animaux
            ajoute le mot [aime], ligne = 2 position = 2
            ajoute le mot [beaucoup], ligne = 2 position = 7
            ajoute le mot [ces], ligne = 2 position = 16
            ajoute le mot [petits], ligne = 2 position = 20
            ajoute le mot [animaux], ligne = 2 position = 27
    mot [aime]
            ligne = 1 position = 3
            ligne = 2 position = 2
    mot [animaux]
            ligne = 2 position = 27
    mot [beaucoup]
            ligne = 2 position = 7
    mot [ces]
            ligne = 2 position = 16
    mot [dans]
            ligne = 1 position = 17
    mot [est]
            ligne = 0 position = 9
    mot [gambader]
            ligne = 1 position = 8
    mot [petit]
            ligne = 0 position = 16
    mot [petits]
            ligne = 2 position = 20
    mot [savane]
            ligne = 1 position = 25
    mot [sensible]
            ligne = 0 position = 28
    mot [tapir]
            ligne = 0 position = 3
    mot [être]
            ligne = 0 position = 22
    

    A toi de compléter la fonction is_delim (si tu veux rajouter les ponctuations en particulier, sachant que la fonction isalpha va sans doute t'intéresser, inclure auquel cas <ctype>), utiliser la fonction tolower (inclure <ctype>) pour ignorer la casse, etc...

    Bonne chance
    1
    1. velderama Messages postés 203 Statut Membre 10
       
      Le programme marche nickel encore merci par contre:

      - j'ai remarqué que un fichier texte d'une certaine taille ne peut etre ouvert 2ko??
      -Egalement
      j'aimerai faire une classe identique a celle la qui prend un autre fichier
      et une 3eme classe qui fait la comparaison des 2 fichiers (ou map)
      comment je dois proceder le plus simplement?
      Encore bravo !!
      0
  2. velderama Messages postés 203 Statut Membre 10
     
    Je vais tout de suite le tester !!
    J'aurai peut etre des questions sur quelles fonctions utilisées ici...
    oui je suis un néophyte de c++ entre les pointeurs et les conteneurs ma foi je m'y perds...lol
    Merci
    0
  3. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 943
     
    J'aurai peut etre des questions sur quelles fonctions utilisées ici...
    oui je suis un néophyte de c++ entre les pointeurs et les conteneurs ma foi je m'y perds...lol


    Qu'est ce que tu ne comprends pas ?

    - j'ai remarqué que un fichier texte d'une certaine taille ne peut etre ouvert 2ko??

    Je ne vois pas pourquoi, il faudrait que tu mettes ton fichier sur cjoint et je testerai.

    j'aimerai faire une classe identique a celle la qui prend un autre fichier

    Il suffit d'appeler la même fonction et de remplir une autre map.

    et une 3eme classe qui fait la comparaison des 2 fichiers (ou map)

    Il suffit d'écrire une fonction qui prend en paramètre deux map et qui les parcourt. Il faudrait que tu dises un peu plus précisément ce que tu entends par comparaison.

    Bonne chance
    0
    1. velderama Messages postés 203 Statut Membre 10
       
      un peu plus précisément ce que tu entends par comparaison.

      les 2 fichiers doivent etre identiques pour cela j'aimerai comparer les 2 map
      les mots appartenant au premier fichier(map) doivent etre les meme dans le second fichier(map)
      (meme mot et meme position)
      ps:
      Avec le code que j'ai la valeur est un "set "qui est encore un conteneur si je ne me trompes pas!
      nb : il est inutile d'enregistrer le numero de ligne donc j'ai essayé de mettre un type int
      pour que ca soit plus simple a utiliser mais ca ne fonctionne pas!
      std::map<std::string,std::int pos> mots;

      Merci
      0
  4. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 943
     
    Le truc c'est que tu vas le faire et si tu bloques je t'aide :-) Je t'invite à lire une tutoriel STL mais avec ce que je t'ai déjà donné tu devrais t'en sortir, c'est toujours la même chose. Le type std::int n'a pas vraiment de sens mais tu peux utiliser des std::size_t (entier positifs) si tu veux.

    Bonne chance
    0
    1. velderama Messages postés 203 Statut Membre 10
       
      ok j'essaie de faire une fonction qui compare les 2 map...
      Merci bcp
      0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. velderama Messages postés 203 Statut Membre 10
     
    Comment garantir que le mot est unique dans le map?
    ....
    if(mot.size()>=3 ){
    cout << "\tajoute le mot [" << mot << " ]position = " << pos << std::endl;
    //ajout de mot et sa position dans le map
    bool b = Verifdoublon(mot,mots);
    if(b==false)mots.insert( make_pair( mot, beg ) );

    }//if(mot.size()>=3)
    ....
    bool Verifdoublon(string s,std::map<std::string,int > m){
    bool res =false;
    map<std::string,int >::const_iterator
    mots_it (m.begin()),
    mots_end(m.end());
    for(;mots_it!=mots_end && res==false;++mots_it){
    const std::string & mot_cur = mots_it->first;
    if( strcmp(s.c_str(),mot_cur.c_str())== 0) {
    m.erase(mot_cur->first);

    res=true;}
    }
    }
    0
  7. velderama Messages postés 203 Statut Membre 10
     
    je pensais a utiliser un count afin d'interdir l'ecrire lorsque count >1 comme ceci

    map<string, int>::size_type size;
    if(mot.size()>=3 ){
    cout << "\tajoute le mot [" << mot << "] position = " << pos<<endl;

    size=mots.count(mot);
    //test
    cout<<" \tnombre de fois"<<size<<endl;
    // mots.insert( make_pair( mot, pos ) );

    }
    ...
    mais ca ne scrute pas le map?...
    0
  8. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 943
     
    Ouvre un nouveau sujet avec ton code complet et expliquant clairement ton nouveau problème. Je t'invite dans un premier temps à regarder comment fonctionne les maps
    https://community.hpe.com/t5/custom/page/page-id/HPPSocialUserSignonPage?redirectreason=permissiondenied&referer=https%3A%2F%2Fcommunity.hpe.com%2Ft5%2FServers-Systems-The-Right%2FSGI-com-Tech-Archive-Resources-now-retired%2Fba-p%2F6992583

    Bonne chance
    0