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 :

Afficher du contenu au hasard a partir d'un fichier


Sujet :

C++

  1. #1
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    201
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 201
    Par défaut Afficher du contenu au hasard a partir d'un fichier
    Bonjour

    je possede le fichier "oneliners" (en piece jointe) qui contient des jokes. Je voudrais que mon pogramme en affiche une au hasard, a chaque fois que l'utilisateur tape Y.

    Voici mon 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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    # include <iostream>
    # include <fstream>
    # include <iomanip>
    # include <cstdlib>
    using namespace std;
    # define   INFILE   "oneliners" /* fichier a ouvrir */
     
    main ( )
    {
      ifstream f;  /* pointeur */
      static long offset [ 100 ]; /* array ou stocker les jokes */
      int c = 0; /* compteur */
      char iline [ 81 ]; 
      char yesno; /* variable pour l'input (Y/N) */
     
      srand (time (NULL)); /* initialisation du generateur */
      int joke; A
     
      f.open ( INFILE );
      if ( ! f.is_open ( ) ) {
        cerr << "Unable to open " << INFILE << "!\n\n";
        exit ( 1 );
        }
     
      /*
       * Boucle pour lecture du fichier 
       */
      while ( f.getline ( iline, 81) ) {
        if ( iline [ 0 ] == '\0') {      /* a chaque espace chaque joke */
          offset [ c ] = f.tellg ( );   /* utiliser ftell pour y assigner une position */
          c ++; /* incremenation du compteur */
          }
        }
     
      for ( c = 0; offset [ c ] > 0; c ++ ) {
        f.clear ( );
        f.seekg ( offset [ c ] ); /* chercher la position ? */
        f.getline ( iline, 81 );   /* lire la ligne suivante */
        cout << setw ( 3 ) << c + 1 << ". " << iline << endl;
      }
     
      cout << "\n You have "<< c << " jokes. \n";
      cout << "\n Do you want hear a joke ? (Y/N) > ";
      cin >> yesno;
     
     while ( yesno == 'Y' || yesno == 'y' ) {
      joke = rand()  % 16 + 1;
      cout << "\n A random joke would be number " << joke << "\n";
      cout << offset[c] << endl;
      cout << "\n\n Do you want hear a joke ? (Y/N) > ";
      cin >> yesno;
     }
    }
    Je suis bloque sur plusieurs points.

    Est ce que, d'abord, l'utilisation du seekg() et tellg() s'accorde avec le principe de mon programme ?

    Je ne crois pas bien proceder avec la generation de 1 jusqu'a 16... ( 16 etant le nombre de joke dans le fichier).

    Mais je n'arrive pas a afficher une joke au hasard

    Dernier point difficile, une joke ne contient pas qu'une ligne elle peut contenir deux. Comment regler ce probleme aussi ?

    Merci de votre aide.
    Fichiers attachés Fichiers attachés

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Bonjour,
    as tu regardé un peut la FAQ??

    Sinon, t'as methode pour se repositionné dans un fichier semble bonne. TU pourrai aussi lire ton fichier et stocker les blague dans un vector<std::string>.
    Quelque conseil:
    1- remplace static long offset [ 100 ]; par std::vector<long> offset(100);
    2- remplace char iline [ 81 ]; par std::string iline et lit le fichier comme dans la FAQ
    http://cpp.developpez.com/faq/cpp/?p...ture_par_ligne
    Ici ca semble faux...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      joke = rand()  % 16 + 1;
      cout << "\n A random joke would be number " << joke << "\n";
      cout << offset[c] << endl;
    1- joke = rand() % 16 + 1; te donnera un ciffre entre 1 et 16... hors les indice d'un tableau vont de 0 a N-1.
    http://c.developpez.com/faq/?page=no..._random_bornes
    2- cout << offset[c] << endl; d'ou vien ce c ??? tu calcul un indice aleatoire et tu utilise un variable qui doit etre fausse....

    Voila.
    Corrige un peu tout cela est cela devrait marcher

  3. #3
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    201
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 201
    Par défaut
    merci pour la reponse

    mais j'ai des erreus de compilation quand je remplace char iline [ 81 ] par std::string iline et static long offset [ 100 ] par std::vector<long> offset(100);

    Et comment stocker les blagues dans vector<std::string> ? Pourrais-tu etre un peu plus explicite ?

    D'autres reponses et points de vues sont les bienvenus.

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par virtuadrack Voir le message
    merci pour la reponse

    mais j'ai des erreus de compilation quand je remplace char iline [ 81 ] par std::string iline et static long offset [ 100 ] par std::vector<long> offset(100);
    quelles erreurs as tu?
    as tu ajouter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #include <string>
    #include <vector>

    Citation Envoyé par virtuadrack Voir le message
    Et comment stocker les blagues dans vector<std::string> ? Pourrais-tu etre un peu plus explicite ?
    tu fait une lecture ligne as ligne,
    http://cpp.developpez.com/faq/cpp/?p...ture_par_ligne
    et quand tu as fini une blague, tu l'ajoute as ton std::vector<std::string> avec un push_back

  5. #5
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    201
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 201
    Par défaut
    Je n'ai plus les erreurs de compilations...

    en fait, je suis quelqu'un qui a travaille 2 semestres avec C...

    et c'est vers la fin qu'on nous demande de switcher au C++

    et c'est pas chose facile de se familiariser avec la syntaxe, la transition est difficile... surtout quand on a que 4 jours avant la fin

    c'est a cause que j'utilisais gcc pour compiler au lieu g++

    anyway, il n'y aurait pas une doc qui pourrait m'expliquer comment ecrire la fonction push_back... car c'est la premiere fois que j'ai affaire au std:: et vetor

    Comment il y aura une interaction entre l'array offset et la fonction push_back ?

    Merci de ton aide.

  6. #6
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par virtuadrack Voir le message
    Je n'ai plus les erreurs de compilations...

    en fait, je suis quelqu'un qui a travaille 2 semestres avec C...

    et c'est vers la fin qu'on nous demande de switcher au C++

    et c'est pas chose facile de se familiariser avec la syntaxe, la transition est difficile... surtout quand on a que 4 jours avant la fin

    c'est a cause que j'utilisais gcc pour compiler au lieu g++

    anyway, il n'y aurait pas une doc qui pourrait m'expliquer comment ecrire la fonction push_back... car c'est la premiere fois que j'ai affaire au std:: et vetor

    Comment il y aura une interaction entre l'array offset et la fonction push_back ?

    Merci de ton aide.
    C'est vrai que ce n'est pas évident de savoir ce qui est plus adapté au C++. Surtout qu'une partie du C est implémenté en C++.

    Pour gcc, c'est bizzare, normalement il aurait du appeler g++. Si ton fichier as une bonne extension. comme : .cc .cpp .cxx ....

    Pour le vector, un peu coup de google est voila
    http://www.cplusplus.com/reference/stl/vector/
    En gros, push_back va augmenter la mémoire du tableau et ajouter un élément.

    Si t'as d'autre question, n'hésite pas a mettre un peu de code comme exemple. C'est plus facile pour te répondre

  7. #7
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    201
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 201
    Par défaut
    Merci pour le lien.

    Voila un peu a quoi je suis arrive a faire.

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    #include <cstdlib>
    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    #include <ctime>
     
    class RandomJoke
    {
    public:
       int show(int p)
       {
          srand( ( unsigned )time( 0 ) );
          int random_integer;
     
          random_integer = ( rand ( ) % p ) + 1;
          return random_integer;
        }
    };
     
    int main()
    {   char yesno;
        std::ifstream read ("oneliners");
     
        std::string line;
        std::vector < std::string > stuff;
     
        int counter = 0;
        while (getline(read, line, '\n'))
        {
          stuff.push_back( line );
          counter++;
        }
     
        read.close();
     
        RandomJoke a;
        int jokes = counter - 1;
        std::cout << "\n You have "<< counter <<" jokes.\n";
        std::cout << " Would you like to hear a joke ? > ";
        std::cin >> yesno;
        loop1:
        if ( yesno =='y' || yesno == 'Y'){
          std::cout << "\n " << stuff[a.show( jokes )];
          std::cout << "\n\n Would like to hear another one ? (Y/N) > ";
          std::cin >> yesno;
          if ( yesno == 'y' || yesno =='Y') goto loop1;
          else EXIT_SUCCESS;
          }
     
        std::cin.get();
        return 0;
    }
    mais reste quelques imprefections...

    le fichier d'entrée "oneliners" (attachée en piece jointe en dans mon premier post) contient des lignes vide, mais mon programme ne sait pas les sauter, car il les lit et les met dans un vecteur

    quand j'execute mon prog, celui-ci m'affiche aleatoirement ces lignes vides

    comment ne pas les lire, ou tout simplement ne pas les afficher ??

    autre question, pourrais-tu reflechir avec moi sur une astuce qui n'affiche jamais une blague deux fois... sauf si ils ont toutes ete affichees...

    finalement, y aurais pas une alternative au goto que j'utilise vers la fin ? je sais que c'est pas conseille

    merci encore

  8. #8
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par virtuadrack Voir le message
    le fichier d'entrée "oneliners" (attachée en piece jointe en dans mon premier post) contient des lignes vide, mais mon programme ne sait pas les sauter, car il les lit et les met dans un vecteur

    quand j'execute mon prog, celui-ci m'affiche aleatoirement ces lignes vides

    comment ne pas les lire, ou tout simplement ne pas les afficher ??
    il est plus propre ton code
    quelques aide :
    - stuff.rbegin() donne un iterateur sur le dernier élément
    - il existe l'opérateur += sur les string
    - tu peut tester si une string est vide ou constitué que d'espace et de tab

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     if (str.empty() || str.find_first_not_of(" \t")==string::npos) std::cout <<"string vide"<<std::endl;
    http://www.cplusplus.com/reference/s..._first_of.html

    Citation Envoyé par virtuadrack Voir le message
    autre question, pourrais-tu réfléchir avec moi sur une astuce qui n'affiche jamais une blague deux fois... sauf si ils ont toutes ete affichees...
    un vecteur de int constitué de chiffre de 0 à nbJoke-1
    et lui appliquer l'algo random_shuffle
    http://r0d.developpez.com/articles/algos-stl/#LII-D-4


    Citation Envoyé par virtuadrack Voir le message
    finalement, y aurais pas une alternative au goto que j'utilise vers la fin ? je sais que c'est pas conseille

    une boucle while() {...}
    ou do {...} while()

    Bon courage

  9. #9
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    201
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 201
    Par défaut
    deja, j'ai reussi a exclure les lignes vides

    et j'ai ameliorer mes boucles

    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    #include <cstdlib>
    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <string>
    #include <ctime>
     
    class RandomJoke
    {
    public:
       int show(int p)
       {
          srand( ( unsigned )time( 0 ) );
          int random_integer;
     
          random_integer = ( rand ( ) % p ) + 1;
          return random_integer;
        }
    };
     
    int main()
    {   char yesno;
        std::ifstream read ("oneliners");
     
        std::string line;
        std::vector < std::string > stuff;
     
        int counter = 0;
        while ( getline(read, line, '\n') ) {
         if (line[0] != NULL ) {
             stuff.push_back( line );
             std::cout << line << std::endl;
             counter++;
             }
          }
     
        read.close();
        system("clear");
        std::cout << "\n You have "<< counter <<" jokes.\n";
        do {
            RandomJoke a;
            int jokes = counter - 1;
            std::cout << "\n\n Would you like to hear a joke ? > ";
            std::cin >> yesno;
            std::cout << "\n " << stuff[a.show( jokes )];
          } while (  yesno =='y' || yesno == 'Y' );
     
        std::cin.get();
        return 0;
    }
    en ce qui concerne random_shuffle, j'aurais vraiment besoin d'aide car j'ai pas su l'incorporer a mon code...

    comment ferais-je ?

  10. #10
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par virtuadrack Voir le message
    en ce qui concerne random_shuffle, j'aurais vraiment besoin d'aide car j'ai pas su l'incorporer a mon code...

    comment ferais-je ?
    montre un bout de code et je te dirait ce qui ne va pas

  11. #11
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    201
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 201
    Par défaut
    le probleme c'est que j'ai pas compris le concept de random shuffle


    j'ai vu l'exemple que t'as donne

    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
    bool GetRandomAlbum( Album& album )
    {
    	// si la liste est vide, on retourne false
    	if ( main_list_.size() == 0 )
    		return false;
     
    // on génère la graine
    	srand( clock() );	
     
    	// on modifie aléatoirement l'ordre le main_list_ 
    std::random_shuffle( main_list_.begin(), main_list_.end() );
     
    // on copie le premier élément de main_list_ dans le resultat
    	album = main_list_[0];
    	return true;
    }
    mais j'ai pas saisi comment ce code va empecher l'affichage d'un blague deux fois jusqu'a ce qu'elles soient toutes affichees...

  12. #12
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    std::random_shuffle
    va te mélanger aléatoirement les éléments contenu entre les deux itérateur.
    Hors tu veut eviter que l'on est deux fois la même blaque.
    Pour il n'y as qu'une solution :
    faire un tableau d'indice que l'on va mélanger aléatoirement.

    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
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <ctime>
    #include <iterator>
    using namespace std;
     
    int main()
        {
        //initialise la graine aléatoire
        srand(time(0));
        std::vector<int> myVect;
        //initialise un vector des chiffre 1 a 9
        for (int i=0;i<10;++i) myVect.push_back(i);
        //affiche le vector
        std ::copy(myVect.begin(),myVect.end(),ostream_iterator<int>(cout,"  "));cout<<endl;
        for (int i =0;i<20;++i)
            {
            //mélange aleatoirement le vector
            random_shuffle(myVect.begin(),myVect.end());
            //affiche le vector
            std ::copy(myVect.begin(),myVect.end(),ostream_iterator<int>(cout,"  "));cout<<endl;
            }
        return 0;
        }
    Tu pourrai aussi mélanger tes blague avec random_shuffles et à chaque yes tu passe à la suivante

    Pour tester si la ligne est vide fait plustôt le test que je t'ai donné.
    Pour les blague sur plusieurs lignes, ben faut que tu test :
    tant que je n'ai pas une ligne vide c'est toujours une blague.
    Tu peut mettre le caracère \n dans une string

    bon codage

Discussions similaires

  1. Afficher le contenu d'un panel à partir d'un bouton
    Par zied_m dans le forum AWT/Swing
    Réponses: 0
    Dernier message: 25/03/2013, 23h58
  2. Réponses: 6
    Dernier message: 01/03/2011, 11h13
  3. [MySQL] Afficher le contenu d'une table à partir des champs d'une autre
    Par cheik_koita dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 15/03/2009, 17h55
  4. [snmp] afficher le contenu d'une trap snmp dans un fichier
    Par liverbird dans le forum Développement
    Réponses: 4
    Dernier message: 20/07/2007, 13h49
  5. Réponses: 3
    Dernier message: 27/01/2006, 18h35

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