Débutez en c++ n°3

Comment debuter en c++

Description

Dans ce tutoriel, nous découvrons la librairie standard string, qui va nous simplifier la vie.

Liens Vers les autres tutoriels de la série :

Bioopo

Le 31/12/2006

Introduction

Nous allons commencer ce tutoriel par voir ce qui ne va pas pour l'utilisateur. Nous allons voir les librairies standard du c++, comment les utiliser et pourquoi. Une fois notre projet terminé, nous avons vu qu'il n'y avait pas de bugs, Génial !!!! Mais faire trois saisies clavier pour une opération aussi simple, c'est même plus terrible, c'est catastrophique.

De plus, nous sommes limités, pour le nombre d'opérations, par l'utilisation de variables unique à chaque saisie, vous imaginez, si vous voulez que votre calculatrice puisse effectuer 20 opérations, ça serait aberrant, un code très long et pas forcément fonctionnel.

La troisième chose est le fait que nous ne pouvons saisir qu'une seule opération, pour en faire une seconde, nous devons relancer le programme. Un petit menu serait le bienvenu.

Voilà, ça sera la base pour notre mise a jour. Fixons les buts clairement :

  • Une seule saisie par opération.
  • Un menu pour choisir de faire une nouvelle opération ou de quitter le programme.
  • Un système pour effectuer un grand nombre d'opération.

Connaissances requises

Les connaissances requises sont celles acquises aux tutoriels numéro 1 et 2 : Débutez en c++. Il faut savoir :

  • Définir une variable et son type. (char, int et double)
  • Initialiser les variables
  • Faire un calcul de base en mathématiques
  • Créer une fonction de test standard (if, if else if)
  • Enregistrer une variable a partir d'une saisie au clavier (cin)
  • Afficher à l'écran un message ou une variable. (cout)
  • Insérer des commentaires
  • Définir, déclarer et appeler une fonction
  • La portée des variables : globales et locales
  • Définir et initialiser un tableau
  • Les fonctions de boucle while et for
  • La fonction de choix switch
  • La conversion de chaine de caractère en double
  • La création d'un fichier d'entête
  • Le passage des arguments à une fonction.

Cahier des charges

Le but du programme

Le but du programme est d'afficher le résultat d'une opération saisie par l'utilisateur.

Les moyens mis en oeuvre

Nous allons utiliser le logiciel dev-c++ avec un nouveau projet en mode console.
Pourquoi le mode console?
Simplement car pour la calculatrice que nous allons programmer, une interface graphique est inutile. Surtout, elle nous rendrait l'apprentissage plus difficile, ce qui n'est pas le but. L'exécutable de la calculatrice ne devra pas dépasser 500 Ko.

Les mises à jour

  • Ajout d'un menu permettant de saisir une opération ou de quitter le programme.
  • Conversion des variable en type string.
  • Une seule saisie par opération, maximum 9 opérations différentes dans une saisie.

Analyse fonctionnelle

Pour notre troisième tutoriel, nous devons modifier les analyses fonctionnelles et structurelles de notre projet initial, nous rajoutons la fonction FA1 : Menu.

Fonction FP0 : Calculatrice

Spécificités Détails
Code d'identification FP0
Nom Calculatrice
Objectif Afficher le résultat d'une opération saisie par l'utilisateur
Données fournies Aucune
Actions utilisateur Saisie de l'opération
Données sorties Résultat de l'opération
Sous-fonctions FP1 : Enregistrement saisie
FP2 : Calcul
FP3 : Affichage du résultat
FP4 : Vérification des saisies
FA1 : Menu
Description détaillée La calculatrice devra, en fonction de la saisie de l'utilisateur, calculer et afficher le résultat de l'opération.

Fonction FP1 : Enregistrement saisie

Spécificités Détails
Code d'identification FP1
Nom Enregistrement saisie
Objectif Enregistrer les saisies utilisateur
Données fournies Aucune
Actions utilisateur Saisie de l'opération
Données sorties Saisie enregistrée
Sous-fonctions Aucune
Description détaillée La Fonction devra enregistrer la saisie utilisateur.

Fonction FP2 : Calcul

Spécificités Détails
Code d'identification FP2
Nom Calcul
Objectif Effectuer le calcul de l'opération saisie par l'utilisateur
Données fournies Saisie enregistrée
Actions utilisateur Aucune
Données sorties Résultat du calcul
Sous-fonctions Aucune
Description détaillée La Fonction devra choisir quel est le calcul a effectuer en fonction de la saisie de l'utilisateur.

Fonction FP3 : Affichage du résultat

Spécificités Détails
Code d'identification FP3
Nom Affichage du résultat
Objectif Afficher le résultat de l'opération
Données fournies Résultat du calcul
Actions utilisateur Aucune
Données sorties Résultat affiché
Sous-fonctions Aucune
Description détaillée La Fonction devra afficher le résultat de l'opération saisie.

Fonction FP4 : Vérification saisie

Spécificités Détails
Code d'identification FP4
Nom Vérification saisie
Objectif Validation de la saisie utilisateur
Données fournies Saisie enregistrée
Actions utilisateur Aucune
Données sorties Saisie validée
Sous-fonctions Aucune
Description détaillée La Fonction devra vérifier la saisie utilisateur et la valider. Si elle n'est pas valide, l'utilisateur devra saisir une nouvelle opération.

Fonction FA1 : Menu

Spécificités Détails
Code d'identification FA1
Nom Menu
Objectif Création d'un menu pour la calculatrice
Données fournies Aucune
Actions utilisateur Saisie utilisateur
Données sorties Menu choisi
Sous-fonctions Aucune
Description détaillée La Fonction devra Choisir le code à exécuter en fonction de la saisie utilisateur.

Analyse structurelle

Fonction FP1 : Enregistrement saisie

Spécificités Détails
Code d'identification FP1
Nom Enregistrement saisie
Objectif Enregistrer les saisies utilisateur
Actions utilisateur Saisie de l'opération
Données sorties Saisie enregistrée
Description détaillée La Fonction devra enregistrer la saisie utilisateur.

Nous allons remanier tout le code de cette fonction. Les tableaux que nous avions au tutoriel précédent ne sont pas assez performant et ne répondent pas aux besoins du programme.

Nous allons utiliser une librairie standard du c++. La librairie string.

Les variables de type string servent à enregistrer des chaines de caractères dont la taille n'est pas connue à l'avance.

Les librairies standard du c++

Une librairie est un ou des fichiers que le compilateur inclut lors de la création du programme, contenant des définitions et des fonctions. Nous en utilisons déjà. La librairie iostream et cstdlib. C'est grâce à elles que nous pouvions utiliser les variables et les fonctions. Elles s'incluent grâce a la commande #include au début du fichier. De plus pour chaque fichier créé, il faut inclure les librairies dont nous avons besoin.

Récapitulatif des variables et fonctions de FP1

Variables et fonctions Type Détails
strSaisie string Enregistre les saisies utilisateur
cin Demande la saisie et l'enregistre

Fonction FP4 : Vérification saisie

Spécificités Détails
Code d'identification FP4
Nom Vérification saisie
Objectif Validation de la saisie utilisateur
Données fournies Saisie enregistrée
Données sorties Saisie validée
Description détaillée La Fonction devra vérifier la saisie utilisateur et la valider. Si elle n'est pas valide, l'utilisateur devra saisir une nouvelle opération

Cette fonction se divise maintenant en trois parties, la vérification de la saisie et le chemin a emprunter en fonction de cette vérification, plus le découpage de la saisie. Si la saisie a passé le test de validation, alors nous découpons les nombres et les opérateurs puis nous calculons, sinon nous redemandons la saisie.

Par contre, le code de vérification sera plus simple car nous utiliserons une fonction de spécifique à la librairie string, et nous vérifierons toute la saisie en une seule fois, opérateurs et nombres en même temps.

Nous ne ferons plus appel au code ascii, mais directement aux nombres et aux opérateurs.

La fonction find_first_of

Cette fonction cherche les caractères demandés et retourne leur position dans la chaine. Elle se définit comme suit :
Variable_de_position = variable_String.find_first_of( "caractères à chercher");

Grâce à cette fonction, nous allons chercher les caractères reconnus par le programme, en vérifiant le premier caractère. Si il est un caractère reconnu, la fonction nous renverra sa position. Dans notre programme, comme nous vérifions toujours le premier caractère, ce sera 0 , sinon, c'est qu'il n'est pas un caractère reconnu, et la saisie n'est pas valide.

Cette fonction nous servira aussi à découper les nombres et les opérateurs de l'opération. En cherchant simplement les opérateurs, nous aurons leurs positions.

La fonction erase

Cette fonction permet d'effacer des caractères, elle se définit comme suit :
Variable_Nouvelle = variable_String.erase(x,y);

x est la position du premier caractère à effacer, et y sa longueur.

Dans notre programme, nous effacerons le caractère validé, ce qui décalera les caractères suivants. Nous pourrons revérifier à partir du premier caractère. Cette fonction est détournée ici de son objectif principal, car nous n'effaçons pas un caractère de la vraie saisie, mais une copie temporaire. Le caractère ainsi effacé sera pour nous la validation de ce caractère.

La fonction substr

Cette fonction enregistre une sous-partie de la chaine. Elle se définie comme cela :
Variable_Sous_Chaine = variable_String.substr(x,y);

x est la position ou commence la sous-chaine, et y sa longueur.

Grâce à cela, nous pourrons découper nos nombres et nos opérateurs.

Récapitulatif des variables et fonctions de FP1

Variables et fonctions Type Détails
strSaisie string Enregistre la saisie utilisateur
dblNombre[10] double Enregistre les nombres saisis validés
strOperand[10] string Enregistre les opérateurs
bErreur Bool Enregistre la présence d'erreur
bDecimal Bool Enregistre la présence du point décimal
If Fonction de test
While Fonction de boucle
find_first_of Fonction de recherche de caractères
substr Fonction de découpages de sous-chaines

Fonction FA1 : Menu

Spécificités Détails
Code d'identification FA1
Nom Menu
Objectif Création d'un menu pour la calculatrice
Actions utilisateur Saisie utilisateur
Données sorties Menu choisi
Description détaillée La Fonction devra Choisir le code à exécuter en fonction de la saisie utilisateur.

Cette fonction ne comporte aucune difficulté. C'est une simple saisie, avec un while et un if pour le code à exécuter.

Variables et fonctions Type Détails
intMenu int Enregistre la saisie utilisateur
while Fonction de boucle
if Fonction de test
Cin Fonction de demande de saisie
cout Fonction d'affichage

Développement

Comme nous nous servons de la librairie string, nous l'incluons dans le fichier main.cpp

Fichier main.cpp - Début du fichier
.........

#include <cstdlib>
#include <iostream>
#include <string>
#include "main.h"

.........

Vous devez vous demander pourquoi certains include sont avec <> et d'autres avec "".
Les librairies standard sont notées <> et les fichiers que nous créons sont notés "".

Ne vous arrêtez pas à mes explications, je vous dit le minimum de ce que vous devez savoir, cherchez, documentez-vous, c'est le meilleur moyen de progresser.

Le fichier main.h

/**********************************
Program : calc2007
Fichier : main.h
Créateur : bioopo
Creation : 29/12/2006
logiciel : dev-c++
Version : 0.2a
Modification : 31/12/2006
**********************************/

/**********************************
Ce fichier déclare les fonctions et les variables globales utilisées dans le programme
**********************************/

/**********************************
Fichiers a inclure
**********************************/
//#include <string>

/**********************************
Définition des variables
**********************************/
//Variable contenant la saisie de l'opérateur.
std::string strSaisie = "";

//variable contenant le signe de l'opération
std::string strOperand[10]= {"","","","","","","","","",""};

//Variable contenant les nombres de l'opération
double dblNombre[10]= {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};

//Variable contenant le résultat
double dblResultat = 0.0;

//variable de présence d'erreur
bool bErreur = true;

//variable de présence de decimal
bool bDecimal = false;

/**********************************
Déclaration des fonctions
**********************************/

//Fonction permettant la saisie utilisateur
void Saisie_Utilisateur();

//Fonction permettant la vérification de la saisie utilisateur
void Verification_Saisie();

//Fonction permettant d'extraire les différentes partie de l'opération.
void Extraction();

//fonction de calcul de l'opération
void Calcul();

Voici le fichier main.h en entier, il faut supprimer certaines lignes et les remplacer ou ajouter les nouvelles. Pensez à supprimer les arguments de la fonction Saisie_Utilisateur et Vérification_Saisie, ainsi que la définition et l'initialisation de la variable dblNombre et dblResultat dans le fichier main.cpp. Dans le fichier main.h avant les définitions des variables string ajouter std::, cela signifie que nous utilisons l'espace de nom standard.

Fonction FP1 : Saisie utilisateur

Fichier main.cpp - Fonction Saisie_utilisateur
........

system("PAUSE");
return EXIT_SUCCESS;
}

void Saisie_utilisateur()
{
    cin >> strSaisie;
}

La fonction de Saisie_utilisateur ne contient plus qu'une seule ligne, ce qui rend le code plus rapide, est surtout plus clair. Pensez à supprimer les arguments de la fonction Saisie_Utilisateur.

Fichier main.cpp - Fonction main
.......

/**********************************
Corps de la fonction
**********************************/
//Fonction permettant a l'utilisateur de saisir le premier nombre
cout << "Bioopo-vega calculatrice 2007 version 0.2a" << endl;
cout << "entrez l'opération" << endl;
Saisie_utilisateur();

.....

L'appel de la fonction de saisie utilisateur n'a plus d'argument. Donc nous supprimons le 1 dans les parenthèses, mais ne pas supprimer les parenthèses. Comme la saisie ne se fait plus qu'une fois, pensez à supprimer le code de saisie et vérification des opérateurs et de la seconde saisie des nombres. Voila, la fonction FP1 est terminée, Elle est beaucoup plus simple, moins de code, moins de test.

Fonction FP4 : Vérification saisie

Fichier main.cpp - Fonction Vérification_Saisie
........

        case 2:
            cin >> chrOperand;
            break;
    }
}
/**********************************
Fonction Verification_Saisie
Fonction permettant la vérification de la saisie utilisateur
**********************************/
void Verification_Saisie()
{
    //Nous définissons qu'il y a une erreur pour la première saisie avant vérification
    bErreur = true;
    //Boucle tant qu'il y a une erreur
    while(bErreur == true)
    {
        //Définissons qu'il n'y a pas de décimal de mise avant la vérification
        bDecimal = false;
        //Définissons les variables de positions
        int intPos = 0;
        //définissons une variable temporaire de travail
        string strTemp = strSaisie;
        //Boucle tant que la vérification de la chaine n'est pas finie
        while(intPos == 0 and strTemp != "")
        {
            //Enregistre la position du caractère autorisé en cours
            intPos = strTemp.find_first_of("0123456789.+-*/");
            //Test si Le caractère est autorisé.
            if(intPos == 0)
            {
                bErreur = false;
                strTemp = strTemp.erase(0,1);
            }
            //sinon ne pas valider la saisie
            else
            {
                bErreur = true;
                break;
            }
        }
        //Si il y a une erreur, nous demandons de rentrez un nouveau nombre
        if(bErreur == true)
        {
            cout << "vous n'avez pas rentré un nombre correct" << endl;
            cout << "entrez un nombre correct" << endl;
            Saisie_Utilisateur();
        }
    }
}

Vous voyez l'intérêt des librairies standard. Maintenant, Le code prend moins de la moitié de l'ancien. Les fonction de la librairie string facilitent grandement la programmation et de plus, le code s'exécutera plus vite.

Fichier main.cpp - Fonction main
......

/**********************************
Corps de la fonction
**********************************/
//Fonction permettant à l'utilisateur de saisir le premier nombre
cout << "Bioopo-vega calculatrice 2007 version 0.2a" << endl;
cout << "entrez le premier nombre" << endl;
Saisie_Utilisateur();

//Fonction de vérification de la saisie
Verification_Saisie();

//Test pour déterminer le signe de l'opération et calcul l'opération
if(chrOperand == '+')
{
    dblResultat = dblNombre[0] + dblNombre[1];
}

......

Nous appelons donc la fonction de vérification. Il nous reste pour cette fonction à découper et enregistrer les différentes partie de l'opération. Pour cela, il faut ajouter une fonction : la fonction extract.

Fichier main.cpp - Fin du fichier
.......

    //Si il y a une erreur, nous demandons de rentrez un nouveau nombre
    if(bErreur == true)
    {
        cout << "vous n'avez pas rentré un nombre correct" << endl;
        cout << "entrez un nombre correct" << endl;
        Saisie_Utilisateur();
        }
    }
}

/**********************************
Fonction Extraction
Fonction permettant d'extraire les différentes partie de l'opération.
**********************************/
void Extraction()
{
    //Définissons la variables de positions
    int intPos = 1,i = 0;
    //Définissons une variable d'enregistrement temporaire
    string strTemp = "";

    //définissons une variable temporaire de travail
    string strTempSaisie = strSaisie;

    //Boucle tant que la l'extraction des nombres est incomplète
    while(intPos != 0)
    {
        //Enregistre la position de l'opérateur
        intPos= strTempSaisie.find_first_of("+-*/");
        //Extraction des nombres
        if(intPos > 0)
        {
            strTemp= strTempSaisie.substr(0,intPos);

            //enregistrement des nombres valides après conversion
            std::istringstream Argument(strTemp);
            Argument >> dblNombre[i];
            //enregistrement de l'opérateur
            strOperand[i]= strTempSaisie.substr(intPos,1);

            //Suppression des nombres validés
            strTempSaisie = strTempSaisie.erase(0,(intPos+1));
            //incrémentation de la position des tableaux d'enregistrement
            i++;
        }
        else
        {
            //enregistrement des nombres valides après conversion
            std::istringstream Argument(strTempSaisie);
            Argument >> dblNombre[i];
            break;
        }
    }
}

Nous recherchons les opérateurs et nous faisons une extraction du nombre qui se trouve avant. Puis nous enregistrons l'opérateur, et le nombre après conversion en double.

Puis nous supprimons les données, enregistrons et nous recommençons jusqu'à la fin de chaine.

Il reste a inclure la librairie standard sstream pour pouvoir utiliser la fonction std::istringstream. Cette fonction sert pour la conversion des string vers un autre type, ici un type double.

Fichier main.cpp - Début du fichier
.......

#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include "main.h"

.......

Fonction FP2 : Calcul

Fichier main.cpp - Fin du fichier
......

/**********************************
Fonction Calcul
Fonction de calcul de l'opération
**********************************/
void Calcul()
{
    //Initialisation de la variable de résultat
    dblResultat = dblNombre[0];
    int i = 0;
    //Fonction de boucle tant que le compteur est inférieur au nombre d'opérandes de l'opération
    while(strOperand[i] != "")
    {
        //Fonction de test de l'opérande en cours et calcul le résultat en conséquence
        if(strOperand[i] == "+")
            dblResultat = dblResultat + dblNombre[i+1];
        else if(strOperand[i] == "-")
            dblResultat = dblResultat - dblNombre[i+1];
        else if(strOperand[i] == "*")
            dblResultat = dblResultat * dblNombre[i+1];
        else if(strOperand[i] == "/")
            dblResultat = dblResultat / dblNombre[i+1];
        i++;
    }
}

Pas besoin de commentaire sur cette fonction, à part la fonction sizeof qui permet d'obtenir la taille d'un tableau, comme les élément d'un tableau char ont une taille de 1 caractère, ça nous donne le nombre de caractères, donc ici, le nombre d'opérations.

Nous devons faire un appel à cette fonction.

Fichier main.cpp - Fonction main
......

/**********************************
Corps de la fonction
**********************************/
//Fonction permettant a l'utilisateur de saisir le premier nombre
cout << "Bioopo-vega calculatrice 2007 version 0.2a" << endl;
cout << "entrez le premier nombre" << endl;
Saisie_Utilisateur();

//Fonction de vérification de la saisie
Verification_Saisie();

//Fonction de calcul de l'opération
Calcul();

//Fonction affichant le résultat de l'opération à l'écran
cout << "Le resultat est" << endl;
cout << dblResultat << endl;

.....

Dans la fonction main, effacer tout le code de calcul et placez y l'appel de la fonction. Voila, la fonction de calcul est terminée. Il reste à développer la fonction Fa1 : Menu, que je ne développerais pas ici, je la mettrais dans la partie Compléments, car vous connaissez maintenant toutes les fonctions pour la réaliser.

Post-développement

Voila, la calculatrice fonctionne, le menu aussi. C'est plus sympa, les seuls bugs que j'ai pu rencontrer, c'est dans le choix du menu, si je tapes une opération avec +2 à la fin, il quitte le programme. Le second est encore moins grave, car ce n'est pas un bug, mais nous devons appuyer sur une touche pour quitter après avoir choisi l'option dans le menu. Nous réglerons ça plus tard, car ce ne sont pas des problèmes graves, nous pouvons dire que notre programme est stable, et le passer en version 0.3b.

Récapitulatif

Bases vues dans ce tutoriel :

  • Définir, déclarer et appeler variables et fonctions de la librairie standard string
  • La conversion de variable string en double

Nous avons vu dans ce tutoriel et les précédents:

  • Les types de variables : int, double, char, bool, string
  • Les fonctions : if, if elseif else, switch, for, while, cin, cout.
  • Les fonctions personnalisées de type void.
  • Les tableaux de type char et double.
  • La création de fichier header.
  • Des fonctions de la librairie standard string : find_first_of, erase, substr

Complément

Voici le code de la fonction FA1 : Menu

Fichier main.h
Il faut déclarer une variable pour le choix du menu.Puis déclarer la fonction de menu

int intMenu = 0;  
void Menu();

Fichier main.cpp
Il faut coder la fonction à la fin du fichier écrire :

void Menu()
{
    system("cls" );
    cout << "saisir une operation tapez 1 ou quitter tapez 2" << endl;
    cin >> intMenu;
}

La fonction system("cls" ) efface l'écran.

Puis dans la fonction main :

int main(int argc, char *argv[])
{
    /**********************************
    Définition et initialisation des variables
    **********************************/

    /**********************************
    Corps de la fonction
    **********************************/
    //Fonction permettant a l'utilisateur de saisir le premier nombre
    cout << "Bioopo-vega calculatrice 2007 version 0.2a" << endl;

    Menu();
    while(intMenu != 2)
    {
        if(intMenu == 1)
        {
            system("cls" );
            cout << "entrez l'operation" << endl;
            Saisie_Utilisateur();

            //Fonction de vérification de la saisie
            Verification_Saisie();

            //fonction d'extraction des données de l'opération
            Extraction();

            //Fonction de calcul de l'opération
            Calcul();

            //Fonction affichant le résultat de l'operation à l'écran
            cout << "Le resultat est" << endl;
            cout << dblResultat << endl;
            system("PAUSE");
            Menu();
        }
        else
            Menu();
        }
    if(intMenu == 2)
    {
        //Appel de la function demandant une pause et de presser une touche pour quitter.
        system("PAUSE");
        return EXIT_SUCCESS;
    }
}

Conclusion

Je finirais ce tutoriel en vous disant de bien assimiler la librairie string et ses fonctions, d'essayer de faire des petits programmes utilisant les connaissances acquises avant de vous lancer dans le tutoriel suivant. Les possibilités de programmes sont déjà plus vastes que pour les deux premiers tutoriels. Essayez à nouveau vos anciennes versions, vous allez voir que les changements apportés sont énormes. Nous avons fait un grand bond en avant entre la version 0.2b et celle-ci.

En espérant que ce tutoriel ai pu vous aider et qu'il vous a plu. Bon courage pour la suite.
Merci a tous.

Ce document intitulé « Débutez en c++ n°3 » issu de CodeS SourceS (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Rejoignez-nous