IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Piocher des mots dans un dictionnaire


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2016
    Messages : 8
    Points : 1
    Points
    1
    Par défaut Piocher des mots dans un dictionnaire
    Bonjour tout le monde,
    Depuis quelques temps, je cherche à faire un programme qui pioche un mot au hasard dans un dictionnaire.
    Qu'est-ce qui cloche dans ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    #include <cstdlib>
    #include <string>
    #include <fstream>
    #include <ctime>
    #include <string>
    #include <iostream>
    #include <fstream>
     
    using namespace std;
     
    string piocherMot(){
    	int posimot(0);
        int taille(232578);
        string ligne, returnmot;
        ifstream flux("dico.txt");
    	if(flux){
        srand(time(0));
        posimot = rand() % 232578;
     
    	int i(0);
    	while(i != posimot){
    		getline(flux, ligne);
    		i++;
    	}
    	ligne = returnmot;
    	cout << ligne;
    	return ligne;
    	}
    	else{
    		cout << "Impossible d'ouvrir le fichier";
    	}
    }
     
     
    int main()
    {
    	cout << piocherMot();
    	return 0;
    }
    Comment résoudre ce problème ?

    Merci d'avance de votre aide,
    Alestrio

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    C'est tout pourri avec des valeurs en durs dans tous les coins et usage de fonction C complètement obsolètes et hors de leurs limites d'utilisation.

    Simplifiez-vous la vie, utilisez les primitives C++, au moins pour les tirages aléatoires.
    Stockez l'ensemble des mots dans un std::vector pour ne pas voir de valeur en durs.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2016
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Oui mais justement, c'est un entrainement pour moi de piocher dans un fichier dictionnaire. De quoi parlez-vous quand vous dites "fonctions C primitives" ?

  4. #4
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    696
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 696
    Points : 2 439
    Points
    2 439
    Par défaut
    Bonsoir.

    Il parle des fonctions srand, time et rand qui sont des fonctions C, et à qui on préfère les fonctions de l'entête random.

    Quelques soucis qui sautent aux yeux dans ce code :
    La fonction piocher s'occupe d'ouvrir le fichier, de le lire jusqu'à atteindre une position donnée, puis de retourner la ligne en question. Ça fait beaucoup de responsabilités et à chaque fois qu'on veut avoir un mot aléatoire on réouvre le fichier alors qu'on pourrait juste stocker son contenu.
    Le nombre de lignes 232578 est codé en dur. Donc si on rajoute ou supprime une ligne il peut planter. Pareil pour le nom de fichier, codé en dur.
    La fonction affiche ET retourne le mot recherché. C'est soit l'un soit l'autre.

    Un main propre, selon moi, serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //Charge le fichier en mémoire, et stocke chaque mot dans le vector
    std::vector<std::string> loadDictionary(const std::string& fileName);
     
    //Extrait un mot au hasard du dictionaire
    std::string getRandomWord(const std::vector<std::string>& dico);
     
    int main() {
        std::string word;
        std::vector<std::string> dico;
     
        dico = loadDictionary("dico.txt");
        word = getRandomWord(dico);
     
        std::cout << word << '\n';
    }
    Je te laisse le soin d'implémenter ces deux fonctions
    Je fais appel aux esprits de Ritchie, Kernighan, Stroustrup et Alexandrescu
    Donnez moi la force, donnez moi le courage de coder proprement !

    « Ça marche pas » n'est PAS une réponse convenable, merci de détailler le souci en fournissant l’environnement, le code source, les commandes et les messages d'erreur.

    Ce club possède également un clavardage, on y trouve quelques perles entre deux sessions d'entraides.

  5. #5
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    En dehors du problème de conception souligné dans les précédentes remarques, il y a deux problèmes plus concrets:
    1) tu ne testes pas l'état du flux dans la boucle qui utilise getline; cela te permettrait d'arrêter de lire le fichier s'il est terminé. Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    while (flux && i < posimot) {
      ...
    }
    2) tu ne prévois pas de valeur de retour lorsque le fichier ne peut pas être ouvert, ou lorsque posimot est supérieur au nombre de mots du fichier.
    Cela est à corriger impérativement.

    Pour la conception, je ne suis pas d'accord avec les remarques faites. On peut décider de piocher un mot sans charger l'ensemble du dictionnaire, qui pourrait être d'une taille très importante -ou bien le programme pourrait tourner sur une machine avec une mémoire très limitée. Néanmoins, il faudrait s'y prendre autrement; je pense à deux solutions:
    1) on détermine la taille en caractère du fichier. Cela peut-être fait rapidement grâce aux méthodes seekg et tellg d'un ifstream. Voir l'exemple: http://www.cplusplus.com/reference/i...istream/seekg/ On prend comme nombre aléatoire un numéro de caractère dans le fichier et on décale le curseur jusqu'au précédent retour à la ligne; enfin on avance le curseur d'un caractère: on est au début du mot choisi aléatoirement.
    2) on commence par compter le nombre de retours à la ligne dans le fichier. Puis on procède comme tu l'as fait. Je pense cette méthode plus lente. Elle deviendra peut-être idiomatique avec l'introduction des ranges dans le standard, mais ce n'est pas la question pour le moment

  6. #6
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2016
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Bonjour, j'ai refait mon code avec vos conseils, mais le random n'est pas très "random" .
    Comment avoir quelque chose de vraiment aléatoire ?
    Sachant qu'en plus, j'en ai besoin dans "piocherMot()" et dans "melangerMot()", c'est très embetant de ne pas avoir quelque chose d'aléatoire car c'est la même suite de nombre.
    Le vector, comme l'a dit stendhal666, n'est pas franchement le mieux, sachant que quand je part en voyage (merci Git) je suis sur une Surface qui n'a pas beaucoup de mémoire.

    Merci d'avance,
    Alestrio

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Est-ce que par hasard t'oublierais pas d'initialiser la seed ? Ou l'initialiserais toujours à la même valeur ?
    Pour avoir un aléatoire plus fort, on l'initialise classiquement au timestamp actuel.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  8. #8
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2016
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Est-ce que par hasard t'oublierais pas d'initialiser la seed ? Ou l'initialiserais toujours à la même valeur ?
    Pour avoir un aléatoire plus fort, on l'initialise classiquement au timestamp actuel.
    Bonjour, comment l'initialiser au "timestamp" ? timestamp() ?

  9. #9
    Membre habitué
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Points : 162
    Points
    162
    Par défaut
    Bonjour, on fait comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    auto const seed = std::time(nullptr); // On créé une seed par rapport au temps ( donc tout le temps différent )
    std::default_random_engine engine{seed}; // On créé l'engine et on l'initialise avec la seed
     
    //exemple
     
    std::cout << engine();


    Ps : inclure l'entête chrono et random

  10. #10
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2016
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Bonjour,
    Visiblement, il ne connaît pas l'entête chrono.h et random.h.
    Sans le ".h", j'ai aussi une erreur.
    Si je ne me trompe pas, une entête c'est un #include ?

    Cordialement,
    Alestrio

  11. #11
    Membre habitué
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Points : 162
    Points
    162
    Par défaut
    Ce code fonctionne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #include <iostream>
    #include <random>
    #include <chrono>
     
    int main(void) 
    {
        auto const seed = std::time(nullptr);        
        std::default_random_engine engin { seed };   
     
        std::cout << engin() << std::endl;  
     
        return 0;
    }

  12. #12
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2016
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Ce doit être moi qui a un problème :
    Quand je lance ton code, le message d'erreur qui s'affiche est celui ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    // Under Section 7 of GPL version 3, you are granted additional
    // permissions described in the GCC Runtime Library Exception, version
    // 3.1, as published by the Free Software Foundation.
     
    // You should have received a copy of the GNU General Public License and
    // a copy of the GCC Runtime Library Exception along with this program;
    // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    // <http://www.gnu.org/licenses/>.
     
    /** @file bits/c++0x_warning.h
     *  This is an internal header file, included by other library headers.
     *  Do not attempt to use it directly. @headername{iosfwd}
     */
     
    #ifndef _CXX0X_WARNING_H
    #define _CXX0X_WARNING_H 1
     
    #if __cplusplus < 201103L
    #error This file requires compiler and library support for the \
    ISO C++ 2011 standard. This support is currently experimental, and must be \
    enabled with the -std=c++11 or -std=gnu++11 compiler options.
    #endif
     
    #endif
    Merci de ton aide,
    Alestrio

  13. #13
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Activez le support de C++11 dans votre compilateur.

  14. #14
    Membre habitué
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Points : 162
    Points
    162
    Par défaut
    Ah bah oui, si t'es sur code::block tu dois procéder comme suit : Settings->Compiler->General( Compiler Flags ) -> activer -std=c++11

  15. #15
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2016
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par Disixlis Voir le message
    Ah bah oui, si t'es sur code::block tu dois procéder comme suit : Settings->Compiler->General( Compiler Flags ) -> activer -std=c++11
    Par contre... je suis sur codelite...
    Comme google est mon ami je vais rechercher comment faire !

    EDIT : Trouvé !
    EDIT 2 : Vous allez dire que je suis ch**nt, heuh... embêtant, pardon, mais le nobre donné est trop grand. Comment le tronquer ?

  16. #16
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Comment le tronquer ?
    On ne tronque pas, ça déglinguerait tous les mécanismes de non-biais, etc..

    Google est ton ami :
    http://stackoverflow.com/questions/1...en-0-0-and-1-0

  17. #17
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardennes (Champagne Ardenne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2016
    Messages : 8
    Points : 1
    Points
    1
    Par défaut
    J'avoue, j'ai été bête là dessus. Il suffit de faire un modulo :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     int randa = engine % compterTailleDico()

  18. #18
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Il suffit de faire un modulo :
    NON, tu vas avoir une répartition des tes tirages biaisées.

  19. #19
    Membre habitué
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Mai 2014
    Messages
    227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 227
    Points : 162
    Points
    162
    Par défaut
    Utilise une distribution sur l'engine, comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    std::uniform_int_distribution<unsigned int> distrib( TAILLE_MINI, TAILLE_MAXI );/// exemple -> ( 0, dico.size() -1 )
    std::cout << distrib(engine);

Discussions similaires

  1. Réponses: 5
    Dernier message: 21/01/2007, 00h43
  2. [COM] Trouver des mots dans des PDF et autres documents ?
    Par zyongh dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 02/11/2006, 14h23
  3. [Word] Comment mettre en évidence des mots dans un document ?
    Par ecocentric dans le forum Framework .NET
    Réponses: 1
    Dernier message: 03/08/2006, 16h31
  4. Chercher des mots dans une ligne
    Par chemouz dans le forum C++
    Réponses: 1
    Dernier message: 17/12/2005, 12h42
  5. Comment changer des mots dans un fichier?
    Par ptitbonum dans le forum Linux
    Réponses: 5
    Dernier message: 07/04/2004, 23h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo