Obtenir un mot à partir d'un fichier

Fermé
Othmane-Lh Messages postés 3 Date d'inscription dimanche 12 juin 2016 Statut Membre Dernière intervention 22 août 2016 - 22 août 2016 à 22:26
mamiemando Messages postés 33073 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 16 avril 2024 - 14 nov. 2016 à 10:14
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;
A voir également:

1 réponse

mamiemando Messages postés 33073 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 16 avril 2024 7 748
Modifié par mamiemando le 30/08/2016 à 10:04
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
Chaimae_ch Messages postés 1 Date d'inscription jeudi 10 novembre 2016 Statut Membre Dernière intervention 10 novembre 2016
10 nov. 2016 à 22:57
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
mamiemando Messages postés 33073 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 16 avril 2024 7 748
Modifié par mamiemando le 14/11/2016 à 10:16
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