Obtenir un mot à partir d'un fichier

Othmane-Lh Messages postés 5 Statut Membre -  
mamiemando Messages postés 33174 Date d'inscription   Statut Modérateur Dernière intervention   -
Salut! Bien, je suis entrain de faire le TP du mot mystère sur openclassrooms et je veux obtenir un ligne spécifié dans un fichier telle que le numéro de la ligne est donner au hasard par l'ordinateur (rand()% ...), bon voilà ma fonction: Le problème c'est que je n'obtient rien dans ma variable mot

string motMystere()
{
    // Focntion pour piocher le mot mystère
    // aucunes paramètres
    // retourne le mot mystère

    ifstream diCo("dico.txt"); // Ouvrir le fichier en mode ecrire

    if(!diCo)
        exit(EXIT_FAILURE); // sortir du programme

    string mot; // le mot mystère
    int nbLigne(0); // Pour compter le nombre de ligne/mot dans notre fichier
    while(getline(diCo, mot))
    {
        nbLigne++; // Incrémenter lors de lire une ligne/mot
    }

    nbLigne=rand()%nbLigne; // Choisir le nombre de ligne dont on va piocher le mot
    nbLigne++; // car le nb choisie est entre 0 et (nbLigne-1)

    diCo.seekg(0, ios::beg); // renvoyer le curseur au début du ficher

    for(int i(0); i<nbLigne; i++)
    {
        getline(diCo, mot); // Sauvgarder le mot mystère dans la variable mot
    }

    return(mot);
}


Qui peut m'aider ?

J'ai inclus la directive ctime, string, cstdlib, fstream et le using namespace std;

1 réponse

  1. mamiemando Messages postés 33174 Date d'inscription   Statut Modérateur Dernière intervention   7 944
     
    Bonjour,

    Tu peux faire comme ceci :

    #include <cstdlib>  // EXIT_*
    #include <iostream> // std::cerr
    #include <fstream>  // std::ifstream
    #include <string>   // std::string, std::getline
    
    int main(int argc, char **argv) {
        const char * filename = "/etc/fstab";
        std::size_t j = 14;
        std::string line;
    
        std::ifstream ifs(filename);
    
        if (ifs) {
            for (std::size_t i = 0; std::getline(ifs, line); ++i) {
                if (i == j) break;
            }
        } else {
            std::cerr << argv[0] << ": cannot read "
                      << filename << std::endl;
            return EXIT_FAILURE;
        }   
        
        std::cout << "line = " << line << std::endl;
        
        return EXIT_SUCCESS;
    }


    Ici comme le compteur i part de 0, cela signifie que la 1ère ligne du fichier correspond à j = 0. Si tu préfères numéroter à partir de 1 c'est donc facile à corriger. Ceci dit, compter à partir de 0 est le comportement "classique", c'est notamment cette convention qui est adoptée par
    tail
    sous linux.

    Bonne chance
    0
    1. Chaimae_ch Messages postés 1 Date d'inscription   Statut Membre Dernière intervention  
       
      Vraiment j'ai lis le code de 'othmane' et il me paraît logique même s'il ne fonctionne pas mais j'ai rien compris du deuxième code que vous avez suggéré 'mamiemando' pouvez-vous m'aider ? Merci d'avance
      0
    2. mamiemando Messages postés 33174 Date d'inscription   Statut Modérateur Dernière intervention   7 944
       
      Dans le code que je propose :
      -
      j
      correspond au numéro de ligne que l'on va extraire (supposée être tiré aléatoirement, ici fixée à 14). C'est un entier positif d'où son type
      std::size_t
      .
      -
      filename
      correspond au chemin du fichier dans lequel on va extraire une ligne, ici le fichier
      /etc/fstab
      , qui existe sous tous les linux. C'est une chaîne de caractère constante, donc on utilise
      const char *
      .
      -
      line
      contiendra la ligne qui sera extraite. C'est une chaîne de caractère variable, donc le plus simple est d'utiliser en C++
      std::string
      .

      Ensuite on ouvre le fichier. En C++ on utilise des flux (aussi bien pour lire, typiquement avec
      >>
      ou
      std::getline
      , que pour écrire, typiquement avec
      <<
      ). Ainsi manipuler un fichier en lecture (
      std::ifstream
      ) ou écrire dans la console (qui est vue comme un fichier) avec
      std::cout
      se fait avec les mêmes primitives.
      https://openclassrooms.com/courses/c-les-manipulateurs-de-flux

      De deux choses l'une :

      - soit le fichier s'ouvre avec succès, dans ce cas le test
      if (ifs)
      sera vrai ; Il faudra alors penser à le fermer une fois qu'on a fini de l'utiliser. J'y reviens juste après, regardons d'abord le
      else
      .

      - soit il ne s'ouvre pas (chemin incorrect, permissions insuffisantes...) et dans on affichera un message d'erreur, et on en le fermera pas (vu qu'il n'est pas ouvert). Note que
      std::cerr
      écrit dans la console, mais
      std::cout
      écrit dans la sortie standard tandis que
      std:cerr
      écrit dans la sortie d'erreur standard. Cette distinction est importante pour envisager de faire des tubes (pipes en anglais) avec les résultats ton programme. Si on est dans ce cas on retourne
      EXIT_FAILURE
      . Pour rappel, la valeur retournée par
      main
      correspond au code de retour du programme et permet de savoir à un programme externe si ton programme s'est bien déroulé ou non. Par convention
      EXIT_SUCCESS
      (qui vaut 0) signifie que tout va bien. Toute autre valeur, dont
      EXIT_FAILURE
      , signifie qu'il y a eu un problème.

      Revenons au cas "qui marche".

      Dans le
      if
      , on avance ligne par ligne en incrémentant le numéro de ligne courante
      i
      et en corrigeant
      line
      en conséquence. Une fois que
      i == j
      on a atteint la ligne désirée.
      http://www.cplusplus.com/reference/istream/istream/getline/

      Quand on quitte la boucle,
      line
      contient donc la ligne demandée. On ferme le fichier comme convenu? On conclue le programme en l'affichant dans
      std::cout
      . Comme tout s'est bien passé, on retourne
      EXIT_SUCCESS
      à terme.

      Bonne chance
      0