C++ fichier+map

Résolu/Fermé
velderama Messages postés 199 Date d'inscription mardi 26 février 2008 Statut Membre Dernière intervention 11 mai 2011 - 28 févr. 2008 à 13:42
mamiemando Messages postés 33076 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 avril 2024 - 4 mars 2008 à 20:28
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
A voir également:

7 réponses

mamiemando Messages postés 33076 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 avril 2024 7 748
29 févr. 2008 à 01:20
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
velderama Messages postés 199 Date d'inscription mardi 26 février 2008 Statut Membre Dernière intervention 11 mai 2011 10
29 févr. 2008 à 10:51
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
velderama Messages postés 199 Date d'inscription mardi 26 février 2008 Statut Membre Dernière intervention 11 mai 2011 10
29 févr. 2008 à 10:35
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
mamiemando Messages postés 33076 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 avril 2024 7 748
29 févr. 2008 à 15:42
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
velderama Messages postés 199 Date d'inscription mardi 26 février 2008 Statut Membre Dernière intervention 11 mai 2011 10
29 févr. 2008 à 16:03
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
mamiemando Messages postés 33076 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 avril 2024 7 748
1 mars 2008 à 03:47
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
velderama Messages postés 199 Date d'inscription mardi 26 février 2008 Statut Membre Dernière intervention 11 mai 2011 10
2 mars 2008 à 19:16
ok j'essaie de faire une fonction qui compare les 2 map...
Merci bcp
0

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

Posez votre question
velderama Messages postés 199 Date d'inscription mardi 26 février 2008 Statut Membre Dernière intervention 11 mai 2011 10
4 mars 2008 à 17:04
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
velderama Messages postés 199 Date d'inscription mardi 26 février 2008 Statut Membre Dernière intervention 11 mai 2011 10
4 mars 2008 à 17:22
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
mamiemando Messages postés 33076 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 17 avril 2024 7 748
4 mars 2008 à 20:28
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