Choisissez votre style : colorisé, impression

Série 8
Structures et chaînes de caractères

But

Cette série a pour but de vous faire pratiquer la notion de structure ainsi que les chaînes de caractères.

Préliminaires :

Les fichiers de cette série devront se trouver dans le répertoire ~/myfiles/cpp/serie08. Si ce n'est pas déjà fait, créez un sous-répertoire serie08 dans le répertoire ~/myfiles/cpp.


Exercice 0 : reprise de l'exemple du cours (structures, niveau 0)

Cet exercice est disponible en page 44 de l'ouvrage C++ par la pratique
(page 45 dans la 2e édition).

Le but de cet exercice est de reprendre l'exemple du cours illustrant la gestion des structures.

Cliquez ici si vous souhaitez faire cet exercice.


Exercice 1 : Nombres complexes (structures, niveau 1)

Exercice n°22 (pages 60 et 225) de l'ouvrage C++ par la pratique.
Exercice n°18 du MOOC

Le but de ce programme est d'effectuer les manipulations élémentaires sur les nombres complexes : addition, soustraction, multiplication et division.

Dans le fichier complexes.cc, définissez une structure Complexe représentant un nombre complexe comme deux double (forme cartésienne).

Ensuite, prototypez puis définissez une procédure affiche qui prend un nombre complexe en argument et l'affiche.

Dans le main(), déclarez et initialisez un nombre complexe. Affichez-le. Compilez et exécutez votre programme pour vérifier que tout fonctionne comme prévu jusqu'ici.

Prototypez puis définissez une fonction addition qui prend deux nombres complexes en argument et retourne leur somme.

Testez votre fonction dans le main().

Terminez l'exercice en écrivant puis testant les fonctions soustraction, multiplication et division.

Rappel : la multiplication de z=(x,y) par z'=(x',y') est le nombre complexe z*z'=(x*x'-y*y', x*y'+y*x').
la division de z=(x,y) par z'=(x',y') est le nombre complexe z/z'=((x*x'+y*y')/(x'*x'+y'*y'), (y*x'-x*y')/(x'*x'+y'*y')).

Exemple d'exécution

(1,0) + (0,1) = (1,1)
(0,1) * (0,1) = (-1,0)
(1,1) * (1,1) = (0,2)
(0,2) / (0,1) = (2,0)
(2,-3) / (1,1) = (-0.5,-2.5)

Exercice 2 : Questionnaire QCM (structures + vectors, niveau 2)

Exercice n°24 (pages 61 et 228) de l'ouvrage C++ par la pratique.
Exercice n°19 du MOOC

On cherche ici à faire un programme d'examen sous forme de questionnaire à choix multiple (QCM) où une question est posée et la réponse est à choisir parmi un ensemble de réponses proposées (une seule bonne réponse possible par question).

Dans un programme qcm.cc, définissez une structure QCM comprenant 3 champs :

  1. un champ question, chaîne de caractères, qui contiendra la question à poser
  2. un champ reponses qui sera un tableau de taille variable de chaînes de caractères contenant les réponses proposées
    (c'est un tableau de taille variable car les questions n'auront pas toutes le même nombre de réponses proposées)
  3. un champ entier solution (entier positif) qui contient le numéro de la bonne réponse (dans le champ reponses).

Prototypez puis définissez une procédure affiche qui prend un QCM en argument et l'affiche. Par exemple :

Combien de dents possède un éléphant adulte ?
    1- 32
    2- de 6 à 10
    3- beaucoup
    4- 24
    5- 2

Dans le main(), créez et initialisez le QCM ci-dessus, puis affichez le. Compilez et vérifiez que tout fonctionne correctement jusqu'ici.

Reprenez la fonction demander_nombre (avec 2 arguments, point 4 de l'exercice 2 de la série 5) définie dans ../corrige5/code/proto.cc, et créez une fonction poser_question qui prend un QCM en argument, appelle successivement affiche et demander_nombre et retourne la réponse de l'utilisateur.

Avant de continuer, testez votre programme (affichage de la question et saisie de la réponse).

On cherche maintenant à faire un examen de plusieurs questions. Définissez le type Examen comme un tableau dynamique de QMC. Créez un Examen dans le main(), puis remplissez-le (dans une fonction creer_examen c'est mieux !) avec les questions suivantes (code partiel) :

C++11 C++98
// Question 1
    { "Combien de dents possède un éléphant adulte",
      { "32", "de 6 à 10", "beaucoup", "24", "2" },
      2 // réponse
    },

    // Question 2
    { "Laquelle des instructions suivantes est un prototype de fonction",
      { "int f(0);"     ,
        "int f(int 0);" ,
        "int f(int i);" ,
        "int f(i);"     },
      3 // réponse
    },

    // Question 3
    { "Qui pose des questions stupides",
      { "le prof. de math",
        "mon copain/ma copine",
        "le prof. de physique",
        "moi",
        "le prof. d'info",
        "personne, il n'y a pas de question stupide",
        "les sondages" } ,
      6 // réponse
    }
    

q.question = "Combien de dents possède un éléphant adulte";
q.reponses.push_back("32");
q.reponses.push_back("de 6 à 10");
q.reponses.push_back("beaucoup");
q.reponses.push_back("24");
q.reponses.push_back("2");
q.solution=2; 

q.question = "Laquelle des instructions suivantes est un prototype de fonction";
q.reponses.push_back("int f(0);");
q.reponses.push_back("int f(int 0);");
q.reponses.push_back("int f(int i);");
q.reponses.push_back("int f(i);");
q.solution=3; 

q.question = "Qui pose des questions stupides";
q.reponses.push_back("le prof. de math");
q.reponses.push_back("mon copain/ma copine");
q.reponses.push_back("le prof. de physique");
q.reponses.push_back("moi");
q.reponses.push_back("le prof. d'info");
q.reponses.push_back("personne, il n'y a pas de question stupide");
q.reponses.push_back("les sondages");
q.solution=6; 

Pour terminer :

  1. Posez les questions une à une ;
  2. Comptez le nombre de bonnes réponses
  3. Donnez le score à la fin

Exemple d'exécution

Combien de dents possède un éléphant adulte ?
    1- 32
    2- de 6 à 10
    3- beaucoup
    4- 24
    5- 2
Entrez un nombre entier compris entre 1 et 5 : 2
Laquelle des instructions suivantes est un prototype de fonction ?
    1- int f(0);
    2- int f(int 0);
    3- int f(int i);
    4- int f(i);
Entrez un nombre entier compris entre 1 et 4 : 3
Qui pose des questions stupides ?
    1- le prof. de math
    2- mon copain/ma copine
    3- le prof. de physique
    4- moi
    5- le prof. d'info
    6- personne, il n'y a pas de question stupide
    7- les sondages
Entrez un nombre entier compris entre 1 et 7 : 5
Vous avez trouvé 2 bonnes réponses sur 3.

Exercice 3 : Générateur automatique de lettres (fonctions et chaînes de caractères, niveau 1)

Exercice n°16 (pages 54 et 217) de l'ouvrage C++ par la pratique.
(pages 55 et 217 dans la 2e édition).
Exercice n°17 du MOOC

Le but de cet exercice est d'écrire un programme nommé lettre.cc, qui constituera un générateur automatique (très simpliste) de lettres.

  1. Écrivez tout d'abord une fonction genereLettre (sans argument, et sans valeur de retour). Cette fonction devra simplement produire la sortie suivante à l'écran : (ne vous occupez pas de la mise en évidence)
    Bonjour chère Mireille,
    Je vous écris à propos de votre cours.
    Il faudrait que nous nous voyons le 18/12 pour en discuter.
    Donnez-moi vite de vos nouvelles !
    Amicalement, John.
    

    Invoquez (appelez) simplement la fonction genereLettre depuis la fonction principale main, compilez votre programme et assurez vous de son fonctionnement correct.

Note : On ne vous demande pas de faire saisir les différents arguments au clavier par l'utilisateur, juste d'appeler deux fois la fonction avec les bons arguments dans le main.


Exercice 4 : Segmentation en mots (string, niveau 2)

Exercice n°19 (pages 56 et 219) de l'ouvrage C++ par la pratique.
(pages 56 et 220 dans la 2e édition).
Exercice supplémentaire n°16 du MOOC

Cadre

On s'intéresse ici au problème de la segmentation d'un texte en mots. Le but est de trouver, l'un après l'autre, les différents «mots» d'un texte ; un «mot» étant défini comme une séquence de caractères ne contenant pas de «séparateur». Pour simplifier, on considérera ici que le seul caractère séparateur est l'espace (i.e. ' ').

Par exemple, le texte « heuu bonjour, voici ma chaîne ! » aura comme «mots» : «heuu», «bonjour,» (y compris la virgule ici), «voici», «ma», «chaîne» et «!».

Fonction nextToken

Dans le fichier token.cc, prototypez puis définissez la fonction :

dont le rôle sera d'identifier (par la position de départ et la longueur) le prochain mot à partir de la position from dans la chaîne str. Elle indiquera de plus, par sa valeur de retour, si elle a trouvé un mot ou non.

Cette fonction modifiera donc les arguments from et len de sorte qu'ils déterminent la position du premier caractère du mot trouvé et sa longueur, pour autant qu'un tel mot existe (et dans ce cas la fonction devra retourner true).

Dans le cas où il n'existe plus de mot à partir de from dans str, le résultat retourné par cette fonction nextToken sera false (et les valeurs modifiées de from et len ne seront plus significatives).

Par exemple, si l'on appelle nextToken avec " heuu bonjour, voici ma chaîne ! " dans str et 0 dans from, la fonction retournera true (oui, elle a trouvé un mot : «heuu») et aura modifié from à 1 (ce mot trouvé commence à la position 1) et len à 4 (le mot trouvé a une longueur de 4 caractères).

Si on l'appelle avec la même chaîne, mais 6 dans from, la fonction retournera true (oui, elle a trouvé un mot : «bonjour,») et aura laissé from à 6 (ce mot trouvé commence à la position 6) et len à 8.

Si par contre, on appelle nextToken, toujours avec la même chaîne, mais 32 dans from, elle retournera alors false (non, elle n'a pas trouvé de mot à partir de la position 32).

Application

Depuis le main du programme, vous demanderez à l'utilisateur d'entrer une chaîne de caractères au clavier, et afficherez (en faisant des appels successifs à la fonction nextToken) l'ensemble des mots de la chaîne entrée, à raison de un mot par ligne, placés entre apostrophes.

Utilisez l'exemple de fonctionnement ci-après pour vérifier la validité de votre programme ; faites en particulier attention à ce que les apostrophes entourent les mots sans qu'il y ait d'espace entre les deux.

Vérifiez également que le programme se comporte correctement même lorsque la chaîne entrée se termine par une suite d'espaces.

information Pour lire une ligne entière, utilisez :
getline(cin, ligne_a_lire);
ligne_a_lire est une string.
 
attention Ne pas utiliser :  cin >> ligne_a_lire;
qui ne lit qu'un seul mot (c'est-à-dire s'arrête au premier blanc (espace) rencontré).

Exemple de fonctionnement :

Entrez une chaîne :  heuu bonjour, voici ma chaîne !  
Les mots de " heuu bonjour, voici ma chaîne !  " sont:
'heuu'
'bonjour,'
'voici'
'ma'
'chaîne'
'!'

Exercice 5 : Devoir du MOOC

Vous êtes encouragés à programmer le devoir de la semaine 6 pour vous entraîner à l'utilisation de structures de données.


Dernière mise à jour : $Date: 2017/11/03 17:07:02 $   ($Revision: 1.21$)