Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les tutoriels > Non-Officiels > Programmation > C++ > Lecture du tutoriel

Programme de révision d'anglais

Avatar
Auteur : Xavinou
Créé : le 09/03/2007 20:19:11
Modifié : le 26/05/2008 11:32:52
Noter et commenter ce tutoriel
Imprimer ce tutoriel
Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Bonjour à tous !

J'ai une question à vous poser...

Qui a déjà eu à apprendre des mots de vocabulaire avec leurs traductions ?

MOI ! Et je suis sûr qu'il y a encore d'autres personnes ! :D

Dans ce tutoriel, vous allez apprendre à coder un programme qui vous demande un mot en anglais en vous donnant sa traduction et vice-versa.

Les prérequis

Les outils du C ou du C++ que j'utilise et qui ont été vus avec M@teo21, je n'y reviendrai pas !!

Sommaire du chapitre :

Présentation du principe

Le principe de notre programme est très simple. :D
Il nous donne un mot et on entre la traduction. Si c'est juste, on continue, si c'est faux, il affiche la bonne réponse et il continue.

D'où le programme sort-il les mots ?

D'un fichier texte créé par vous ! :p

Comment connaît-il la traduction ?

La traduction est dans un autre fichier texte créé par vous ! :p

En clair et plus complet :

1. Le programme ouvre le fichier .txt contenant les mots anglais.
2. Il stocke les mots dans un tableau.
3. Il fait de même avec le fichier .txt contenant les mots français.
4. Il prend un mot dans un des tableaux et demande la traduction.


C'est clair ?

Mais si on stocke les mots des fichiers .txt dans des tableaux, il demandera toujours les mots dans le même ordre, et à la longue, on va connaître par coeur les mots parce qu'on connaît l'ordre !

Eh ben non ! :D Il ne demandera pas les mots dans le même ordre, parce qu'on va coder une fonction qui renvoie un nombre aléatoire, et on demandera le mot correspondant à la case du tableau.

Bon, maintenant, passons au codage !! :p

Les notions à connaître

Pour pouvoir continuer, il faut avoir un minimum de connaissances en C++ !
Il faut maîtriser les notions suivantes :

Normalement, les quatre premières parties devraient être connues. Concernant la sixième, je vous renvoie vers un autre de mes tutoriels.

Maintenant, passons à la chose que M@teo21 n'a pas encore vu dans son cours : les vecteurs !

Alors, les vecteurs, c'est... euh... Ben en fait, j'en sais rien ! :D o_O
Cela peut paraître bizarre, mais tout ce que je sais des vecteurs, c'est ça :

Les vecteurs, c'est comme les tableaux, sauf qu'on n'a pas besoin de donner la taille à l'initialisation.

Je sais ça et quelques opérations, mais c'est tout. :D En sachant juste cela, on peut faire notre programme sans le moindre problème :p .
Vous ne me croyez pas ? Ben on verra dans environ... ben maintenant !

Commençons à programmer, à présent ! :)

Le programme

Bien, passons aux choses sérieuses :euh: !

Tout d'abord, l'en-tête du fichier :

Code : C++
1
2
3
4
5
6
7
#include <iostream>   // ça, tout le monde connaît !
#include <string>     // pour les chaînes de caractères
#include <fstream>    // pour lire dans les fichiers
#include <vector>     // pour pouvoir utiliser les vecteurs
#include <ctime>      // pour les nombres aléatoires
 
using namespace std;


J'avais dit précédemment que le programme demanderait un mot aléatoirement. Il faut donc faire une fonction qui renvoie un nombre aléatoire entre 0 et le nombre de mots que l'on a.

Et si on ne connaît pas le nombre de mots ?

Ce n'est pas grave vu qu'on le passera en paramètre dans la fonction !
Voici le code :

Code : C++
1
2
3
4
int aleatoire(const int min, const int max)
{
    return (int)(min+((float) rand()/RAND_MAX*(max - min + 1)));
}


int min représente le nombre minimal de mots, donc logiquement min = 0. On définira cette constante dans la fonction main().

int max représente le nombre de mots au total. Comme on ignore cette constante, on la définira également dans la fonction main().

NB : je passe les paramètres avec le mot clé const pour être sûr de ne pas les modifier !

Donc les mots seront demandés aléatoirement.

Pourquoi ne pas faire en sorte que la langue soit aussi aléatoire, c'est-à-dire que c'est tantôt un mot français qui est demandé, tantôt un mot anglais ?

C'est une bonne idée, on fera cela un peu plus tard, dans la fonction main().

Pour la suite, j'ai choisi de faire une fonction qui prend en paramètre les deux vecteurs et un indice. Cet indice est un nombre aléatoire qui ira "chercher" dans les vecteurs le mot à traduire et sa traduction. J'ai appelé cette fonction traduction.

Cette fonction affiche donc le mot à traduire et demande la traduction. Cette traduction sera entrée par l'utilisateur et stockée dans une chaîne de caractères. Ensuite, elle va comparer la chaîne entrée avec le vrai résultat. Si c'est bon, on affiche un message correspondant, si ce n'est pas bon, on affiche la bonne réponse. On intègrera également une condition d'arrêt.

Bien, vous avez tout ce qu'il vous faut pour écrire cette fonction !

Voici donc le code de cette fonction :

Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
void traduction(vector<string>& tabCherche, vector<string>& tabRes, int alea)
{
    string traduc;
    cout << "Traduiser le mot suivant : " << tabCherche[alea] << " : ";
    cin >> traduc;
 
    if(traduc == tabRes[alea])  //je vérifie la traduction
        cout << "Tres bien" << endl << endl;
    else if(traduc == "0000") // condition d'arrêt
    {
        cout << endl;
        cout << "Fin du test" << endl << endl;
        exit(0);  // pour quitter le programme
    }
    else
        cout << "Eh ben non, la bonne reponse est : " << tabRes[alea] << endl << endl;
}


Remarque : les deux vecteurs sont passés par référence, c'est-à-dire qu'il ne sont pas recopiés dans la mémoire. Cela accélère un peu le programme, surtout s'il y a beaucoup de mots.

Bien, il ne nous reste plus que la fonction main.

Réfléchissons à ce dont nous avons besoin ! :euh:

Il nous faut les constantes min et max utilisées dans la fonction que l'on a vue.

Pour que la fonction aléatoire fonctionne bien, il faut inclure dans le main() : srand((unsigned) time(NULL));. C'est pour initialiser le rand(). Si on ne met pas cette ligne, la fonction renvoie bien un nombre aléatoire, mais à chaque exécution, les nombres sont dans le même ordre.

Ne surtout pas mettre cette ligne dans la fonction aléatoire, sinon, c'est toujours le même nombre qui est renvoyé !

Le début de la fonction main() est donc :

Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
int main()
{
    const int min = 0;
    const int max = 1;
 
    srand((unsigned) time(NULL));  // pour initialiser rand()
 
// le reste du code
 
    return 0;
}


Quand je vous ai présenté le principe du programme, je vous ai dit que le programme ouvre les fichiers .txt et stocke les mots dans un tableau. Les mots du fichier anglais.txt dans un tableau et les mots du fichier francais.txt dans un autre.
C'est ici que nous allons utiliser les vecteurs.

Il faut donc ouvrir les fichiers .txt et mettre tous les mots dans leur tableau respectif (vecteur).

Dans les fichiers .txt, il ne doit y avoir qu'un seul mot par ligne !

Il faut donc une boucle qui mette les mots dans les vecteurs tant que l'on peut lire quelque chose. Auparavant, il faut vérifier si les deux fichiers .txt sont correctement ouverts. Si c'est le cas, on rentre dans la boucle, on prend le premier mot, on le met dans le vecteur (et ainsi de suite), et cela pour les deux fichiers.

Maintenant, quelques rappels sur la manipulation des fichiers.

Il faut utiliser la fonction getline(). Cette fonction prend en paramètre un istream et un string, et lit des caractères du flux jusqu'à un délimiteur de fin de chaîne (on peut décider soi-même de lire jusqu'à un caractère particulier qui soit différent de '\n' (retour la la ligne ;) ). Il faut donc déclarer une chaîne de caractères qui servira à récupérer le mot. L'ouverture d'un fichier en C++ se fait à l'aide de ifstream descripteur("nom_fichier", mode_ouverture);.

Pour plus d'informations, je vous renvoie ici.


Bien, maintenant stockons les mots dans leur vecteur.
Il faut donc ouvrir ces fichiers en mode lecture, vérifier si l'ouverture a réussi, prendre le mot et le mettre dans le vecteur.

Voici le code :

Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
vector<string> tabfr;  // les vecteurs se déclarent comme ceci !
vector<string> taban;
string mot;  // chaîne intermédiaire servant à stocker le mot dans le vecteur
 
ifstream fichierAnglais("anglais.txt", ios::in); // ouverture lecture seule
ifstream fichierFrancais("francais.txt", ios::in);
 
if(fichierAnglais && fichierFrancais)
{
    while(getline(fichierAnglais, mot)) // tant qu'on peut lire dans le fichier
    {
        taban.push_back(mot);  // pour rajouter dans un vecteur
        getline(fichierFrancais, mot);         
        tabfr.push_back(mot);
    }
    fichierAnglais.close();   // fermeture des fichiers
    fichierFrancais.close();
}
else
{
    cerr << "Impossible d'ouvrir un des 2 fichiers !" << endl;
    exit(1);
}


Bien, une bonne partie du programme est maintenant faite.

Il ne nous reste plus qu'à faire la partie dans laquelle il appelle la fonction traduction.
Ce sera dans une boucle de 0 à 100 (100 parce qu'il faut bien s'arrêter un jour ! :p ). C'est également ici que nous nous servirons de notre fonction aléatoire : une fois pour choisir le fichier, et une deuxième pour choisir un mot.

Voici le code :

Code : C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
for(int j = 0; j < 100; j++)
{
    int alea2 = aleatoire(min, max);
    int alea = aleatoire(min, tabfr.size()-1);  // le -1 car dans un vecteur, on compte à partir de 0
 
    if(alea2 == 0) // si c'est 0, il demande un mot français
        traduction(taban, tabfr, alea);
    else // sinon, il demande un mot anglais
        traduction(tabfr, taban, alea);
}


Si vous êtes attentifs, vous aurez remarqué que l'ordre des vecteurs passé en paramètre n'est pas le même. C'est très important l'ordre dans cette fonction !

En effet, dans cette fonction, le premier paramètre représente le vecteur dans lequel se trouve le mot à traduire. Le second paramètre représente le vecteur où se trouve la traduction de ce mot.

C'est quoi, le tabfr.size()-1 ?

C'est la taille du vecteur (le nombre de mots ;) ). Le -1 est obligatoire, car comme dans un tableau, le premier élément ne porte pas le numéro 1, mais 0.

Et voilà, c'est fini !! :D :D

Les fichiers anglais.txt et francais.txt doivent se trouver dans le même répertoire que l'exécutable !


Code complet et optimisations

Voici le code dans son intégralité :

Code : C++
 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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>   // ça, tout le monde connaît !
#include <string>     // pour les chaînes de caractères
#include <fstream>    // pour lire dans les fichiers .txt
#include <vector>     // pour pouvoir utiliser les vecteurs
#include <ctime>      // pour les nombres aléatoires
 
using namespace std;
 
int aleatoire(const int min, const int max)
{
    return (int)(min+((float) rand()/RAND_MAX*(max - min + 1)));
}
 
void traduction(vector<string>& tabCherche, vector<string>& tabRes, int alea)
{
    string traduc;
    cout << "Traduisez le mot suivant : " << tabCherche[alea] << " : ";
    cin >> traduc;
 
    if(traduc == tabRes[alea])  //je vérifie la traduction
        cout << "Tres bien" << endl << endl;
    else if(traduc == "0000") // condition d'arrêt
    {
        cout << endl;
        cout << "Fin du test" << endl << endl;
        exit(0);
    }
    else
        cout << "Eh ben non, la bonne reponse est : " << tabRes[alea] << endl << endl;
}
 
int main()
{
    const int min = 0;
    const int max = 1;
 
    srand((unsigned) time(NULL));  // sert à initialiser le rand()
 
    vector<string> tabfr;  // les vecteurs se déclarent comme ceci !
    vector<string> taban;
    string mot;  // chaîne intermédiaire servant à stocker le mot dans le vecteur
 
    ifstream fichierAnglais("anglais.txt", ios::in); // ouverture lecture seule
    ifstream fichierFrancais("francais.txt", ios::in);
 
    if(fichierAnglais && fichierFrancais)
    {
        while(getline(fichierAnglais, mot)) // tant qu'on peut lire dans le fichier
        {
            taban.push_back(mot);  // pour rajouter dans un vecteur
            getline(fichierFrancais, mot);         
            tabfr.push_back(mot);
        }
        fichierAnglais.close();   // fermeture des fichiers
        fichierFrancais.close();
    }
    else
    {
        cerr << "Impossible d'ouvrir un des 2 fichiers !" << endl;
        exit(1);
    }
 
    for(int j = 0; j < 100; j++)
    {
        int alea2 = aleatoire(min, max);
        int alea = aleatoire(min, tabfr.size()-1);  // le -1 car dans un vecteur, on compte à partir de 0
 
        if(alea2 == 0) // si c'est 0, il demande un mot français
            traduction(taban, tabfr, alea);
        else // sinon, il demande un mot anglais
            traduction(tabfr, taban, alea);
    }
 
    return 0;
}


Bien sûr, un programme n'est jamais parfait ! Il y a toujours moyen de l'améliorer, ce que vous pouvez faire en créant une autre fonction aléatoire encore plus aléatoire ! :p
Vous pouvez également ajouter des fonctionnalités.

Sinon, pour rendre les choses un peu plus jolies, on peut mettre de la couleur. Pour ceci, lisez le tutoriel sur les couleurs dans la console.

Le mien ressemble à ça :
Image utilisateur

Q.C.M.

A quoi peut-on assimiler un vecteur ?
Quelle librairie doit-on inclure pour pouvoir utiliser srand((unsigned) time(NULL)) ?
A un moment, dans le code, il y a tabfr.size()-1. Pourquoi?


Et voilà, c'est fini ! Et en plus, ce n'était pas tellement dur ! :p

Si jamais vous avez des problèmes, ou que vous désirez avoir la version couleur du programme, contactez-moi !

Bonne révision ! :p
Auteur : Xavinou
Noter et commenter ce tutoriel
Imprimer ce tutoriel

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | Fil RSS | XHTML 1.0 | CSS 2.0
Édité par Simple IT SARL : Nous contacter | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 334 Zéros connectés | Requêtes SQL 8 requêtes | Temps de génération de la page : Total (SQL) 0.1887s (0.1748s)