IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Saisie de 10 entiers et recherche


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Novembre 2017
    Messages : 2
    Par défaut Saisie de 10 entiers et recherche
    Bonjour à tous,
    je viens juste de commencer à programmer en C++, j'ai fais un exo mais mon prog ne marche pas correctement est-ce que quelqu'un peut me le corriger SVP
    voici l'exo
    Ecrire un programme qui demande à l'utilisateur de saisir 10 entiers stockés dans un tableau ainsi qu'un entier V. Le programme doit rechercher si V se trouve dans le tableau et doit supprimer la première occurrence de V en décalant d'une case vers la gauche les éléments suivants et en rajoutant un 0 à la fin du tableau. Le programme doit ensuite afficher le tableau final.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    #include <iostream>
    #include <math.h>
    using namespace std;
     
    int main()
    {
     
         int N(0);int T[10];
    int s(0);
     
     
         for(int i(0);i<10;i++) {cin>> T[i];}
     
         cout<<"Tapez la valeur de N : ";cin>>N;
     
       for(int i(0);i<10;i++){
            if(T[i]==N) {i=s;break;return s;};
       }
     
        for(int j=s;j<9;j++){
                T[j]=T[j+1];
                T[9]=0;}
                     for(int i(0);i<10;i++) cout<<T[i]<<endl;
     
     
        return 0;
    }

  2. #2
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 513
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 513
    Par défaut
    Bonjour,

    La technique pour analyser pourquoi ça ne marche pas est d'afficher, en cours de calcul, l'état de tes variables.

    Par exemple, après ton :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for(int i(0);i<10;i++){
    if(T[i]==N) {i=s;break;return s;};
    }
    Si tu ajoutes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::cout << "valeur de s : " << s << '\n';
    Tu devrais constater que s reste à zéro, quoi qu'il arrive.

    Remarque : Plus tard dans l'apprentissage, tu découvriras le débogage pas à pas via un IDE qui permet d'exécuter le code pas à pas et de voir l'état des variables sans avoir besoin d'ajouter des std::cout dans le code.

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    Et sur la ligne if(T[i]==N) {i=s;break;return s;}; en plus de l'erreur d'affectation de s, il y a deux autres problèmes.
    Après break qui fait quitter la boucle, le return s; ne sera pas exécuté et heureusement car return nous aurait fait quitter la fonction. Le compilateur doit indiquer un warning ici. Il est important de lire les warnings.
    Et tout au bout de la ligne le ; pourrait te jouer des tours. Il ne faut pas mettre de point-virgule après une accolade qui ferme un bloc, le point-virgule sert à terminer une expression. Le compilateur émet aussi un warning dans ce cas.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Fais attention à l'utilisation de cin https://cpp.developpez.com/faq/cpp/?...isies-avec-cin
    Soigne la présentation de ton code ça aide à y voir plus clair.
    Utilises un debugger ou ajoute des std::cout pour voir où le programme passe et quelles valeurs sont alors présentes en mémoire.
    Ton utilisation de s est éronnée.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Membre Expert
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Par défaut
    Bonjour,

    j'ai un peu de temps à consacrer à votre question, essayons de le mettre à profil.

    Si vous souhaitez apprendre à coder avec un C++ propre et au goût du jour, voici un aglomérat de remarques concernant votre programme. Coder correctement en C++ c'est :
    • une meilleure lisibilité qui elle permet une meilleure transitivité de la pensée au code (j'écris ce que je pense), et du code à la pensée (le code décrit quoi faire au lieu de comment faire) ;
    • être concis : moins de code = moins de busg et moins d'efforts à lire et à écrire ;
    • des idiomes : il y a tant de façons différente d'opérer la même tâche ; utiliser la méthode idiomatique en C++ réduit le nombre de WTF/ligne, permet un code plus facile à lire (voir lisibilité ci-dessus) et une meilleure communication avec les autres développeurs C++.


    Et quand on code propre, on écrit du code qui marche. Du premier coup (si !). Lanssons-nous.

    1. Inclusions
    Il faut inclure, tout ce qui est nécessaire, seulement ce qui est nécessaire, et préférer les inclusiosn C++ aux inclusions C.

    Tous les standard headers du C (<math.h>, <string.h>, <stdlib.h>, etc.) ont été redéfinis en C++ : enlevez le ".h" à la fin du nom et préfixez d'un "c" (<cmath>, <cstring>, <cstdlib>, etc.). Notamment, ces nouvelles versions définissent leurs identifiants dans le namespace ::std. Voir ci-après.

    Dans le code que vous donnez par exemple, vous n'utilisez pas ce qui est défini dans "math.h", ne l'incluez pas.

    2. using namespace Considered harmful
    Vous trouverez sur l'Internet de nombreux exemples de Vous trouverez aussi beaucoup d'articles valorisant les actions de l'Allemagne nazie (un point goldwin pour moi je vous prie) : n'écoutez pas sans esprit critique les conseils d'inconnus sur l'Internet.

    En déclarant using namespace std;, vous importez dans le namespace global tous les identifiants définis dans ::std, c'est à dire beaucoup de choses, dont notamment beaucoup de mots très courants en programmation : swap, sort, array, vector, list, ... autant de mots que vous pourriez être amené à utiliser pour nommer une variable ou une fonction. En using namespace std;, vous courrez au devant de grands périls.

    De plus, en déclarant using namespace std;, vous vous permettez d'utiliser des identifiants de ::std sans les préfixer de std::, ce qui rend moins évident pour vos lecteurs (y compris vous dans le futur) que vector est bel est bien std::vector et non une classe vector que vous avez défini ailleurs. Voir ce que je dis sur la lisibilité ci-dessus.

    3. Formatter son code proprement
    Choisissez un guide d'écriture et tenez-y vous ! Par exemple Google C++ Style Guide. Ou n'importe quel guide. Mais tenez-y vous.
    Notamment :
    • une ligne = une instruction = une ligne ;
    • respecter le niveau d'indentation ;
    • pas de ligne vide inutile ;
    • déclarer les variables dans le plus petit scope possible, au plus près de leur première utilisation.


    4. Divisez votre code en entités fonctionnelles
    Ecrire un programme qui demande à l'utilisateur de saisir 10 entiers stockés dans un tableau ainsi qu'un entier V. Le programme doit rechercher si V se trouve dans le tableau et doit supprimer la première occurrence de V en décalant d'une case vers la gauche les éléments suivants et en rajoutant un 0 à la fin du tableau. Le programme doit ensuite afficher le tableau final.
    L'énoncé vous demande de :
    1. lire des entiers saisis par l'utilisateur ;
    2. rechercher un entier dans un tableau d'entiers ;
    3. supprimer un élément d'un tableau (en décalant les éléments suivants).

    Ces tâches ne devraient rien avoir à voir entre elles, et c'est l'agencement de ces tâches simples (donc courtes, lisibles, voir ci-avant) qui vous permettron d'écrire un programme.


    5. Lire un entier saisi par l'utilisateur
    Lorsque je lis "saisi par l'utilisateur", j'ai peur. L'utilisateur est un con. L'utilisateur peut saisir tout et n'importe quoi. Mais seul des entiers nous intéressent ici. Et c'est là que std::getline et std::stoi vont nous aider, en nous protégeant de tous les cas de figure (notamment, saisie de l'utilisateur erronée).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #include <iostream>
    #include <string>
    #include <stdexcept>
     
    // Prompts the user to input an integer value. Returns the first integer correctly input.
    int prompt_integer(std::string prompt)
    {
        std::cout << prompt << std::flush;
        for (std::string line ; std::getline(std::cin, line) ;) {
            try {
                return std::stoi(line);
            } catch (std::exception&) {
                std::cout << "invalid value: " << line << "\n" << prompt << std::flush;
            }
        }
        return 0;
    }
    L'interaction avec l"utilisateur est toujours complexe. Je vais vous laisser le soin de prendre le temps de comprendre cet exemple. Je ne vous expliquerai que la seconde ligne : la boucle for.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        for (std::string line ; std::getline(std::cin, line) ;) { /*body */ }
    Cet usage idiomatique casse l'habitude de la boucle for (initialisation ; test ; incrément) car le test modifie line. Suivons l'ordre d'exécution :
    1. Définition de la variable line (vide par défaut).
    2. getline lit une ligne de cin dans line et retourne true si la lecture s'est bien passée.
    3. S'il y a un problème de lecture (fin de fichier notamment, car oui l'entrée standart est un fichier qui peut se terminer), on sort de la boucle.
    4. Le /*body */ est exécuté (celà peut amener à return ... qui sort de la fonction et donc de la boucle).
    5. getline est appelée
    6. Le /*body */ est exécuté.
    7. ...

    Une fois que ceci est compris, on comprend que la fonction prompt_integer demande à l'utilisateur de saisir un entier jusqu'à ce que celui-ci saisisse correctement un entier.

    Voilà, le plus dur est fait. Il ne reste plus qu'à :

    6. Rechercher un entier dans un tableau d'entier pour le supprimer
    C'est comme sur l'appstore : il y a une fonction pour ça : std::remove.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #include <algorithm>
    std::remove(begin, end, value);
    Cela déplace l'element du tableau [begin ; end[ dont la valeur est value à la fin du tableau. Exactement ce que l'on veut. Il ne restera plus qu'à le supprimer après.

    std::remove est en réalité une fonction template, begin et end peuvent avoir quasiment la forme que l'on veut : pointeurs, itérateurs, ...

    7. Supprimer le dernier élément d'un tableau
    Idem, y'a une fonction pour ça : la plupart des conteneurs de la bibliothèque standart ont une fonction membre erase qu'il suffit d'appeler. Cette fonction prend en paramettre la position de l'élément à supprimer qui s'avère être la valeur retournée par std::remove. La nature est bien faite !

    Sauf qu'ici ... on ne veut pas supprimer à proprement parler notre valeur mais la remplacer par zéro. Qu'à cela ne tienne, std::remove retourne justement un itérateur sur l'élément qui a été déplacé à la fin du tableau. Il suffit d'écrire zéro dessus.

    8 Emboiter le tout pour faire un programme
    Si vous lisez ceci, c'est probablement que vous avez pris au sérieux ces conseils et que vous prenez le temps de les lire. Je vous donne donc ici mon implémentation de votre problème. Continuez à lire puis revenez dessus pour expérimenter.

    On récapitule :
    Ecrire un programme qui demande à l'utilisateur de saisir 10 entiers stockés dans un tableau ainsi qu'un entier V. Le programme doit rechercher si V se trouve dans le tableau et doit supprimer la première occurrence de V en décalant d'une case vers la gauche les éléments suivants et en rajoutant un 0 à la fin du tableau. Le programme doit ensuite afficher le tableau final.
    Voici à quoi va donc ressembler notre main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    int main()
    {
        // prompt array
        std::array<int, 10> values = { 0 };
        std::generate(std::begin(values),
            std::end(values),
            [](){ return prompt_integer("entier a stocker: "); }
            );
     
        // prompt value to search & destroy
        const int persona_non_grata = prompt_integer("entier a supprimer: ");
     
        // apply
        find_and_remove_by_zeroing(persona_non_grata, values);
     
        // print
        std::cout << "Valeurs finales : ";
        for (auto n : values) {
            std::cout << n << ", ";
        }
        std::cout << "\n";
    }
    Chaque élément de l'intitulé du problème est traduit par quelques lignes de code. Quelues précisions tout de même :

    C'est équivalent à int values[10]; et il est parfaitement possible de définir values comme ça sans rien changer au reste du code ... mais franchement std::array est vraiment plus safe est plus riche ; à préférer.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::generate(begin, end, generator);
    Cela appelle generator() pour construire chaque élément de [begin ; end[ (voir doc de std::generate). Ici donc, chacun des éléments de values sera le resultat de l'appel à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [](){ return prompt_integer("entier a stocker: "); }
    qui est une lambda : un objet anonyme s'utilisant de la même manière qu'une fonction ne prenant aucun argument (()) et retournant le résultat de prompt_integer("entier a stocker: "). Exactement ce qu'on veut.

    C'est fonctionnellement équivalent à ce qui suit, mais c'est plus explicite (on dit clairement qu'on génère les valeurs) et si la taille de values change, le code de la génération n'a pas à changer.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (int i = 0 ; i < 10 ; ++i) {
    	values[i] = prompt_integer("entier a stocker: ");
    }
    Enfin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find_and_remove_by_zeroing(persona_non_grata, values);
    Il ne reste plus qu'à la définir. Mais elle fait ce qu'elle dit faire.

    9. Le mot de la fin
    J'espère que ces conseils vous amèneront à écrire du meilleur code et vous fera apprécier le C++ récent plutôt que détester le "C with classes" qu'était le vieux C++. N'hésitez pas à poser des questions spécifiques sur certains aspects de ces exemples, et jouez avec le code pour essayer d'autres exercices (par exemple, ne plus lire 10 entiers mais un nombre d'entiers décidé par l'utilisateur).

    Bonne chance.

  6. #6
    Nouveau candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2017
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Novembre 2017
    Messages : 2
    Par défaut s=0
    bonsoir,
    merci d'avoir pris le temps de me répondre.
    le programme ne marchait pas parce que j ai pas remarqué que je me suis trompé dans l affectation c'est s=i et non i=s

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Un programme simple qui ne s'éxecute pas
    Par malcolm41000 dans le forum C++
    Réponses: 3
    Dernier message: 01/10/2013, 18h40
  2. Simple JPA qui marche Pas !
    Par kamaldev dans le forum JPA
    Réponses: 3
    Dernier message: 27/06/2008, 15h54
  3. Réponses: 7
    Dernier message: 27/04/2006, 14h51
  4. [LG]Split qui marche pas
    Par macluvitch dans le forum Langage
    Réponses: 3
    Dernier message: 30/11/2003, 18h19
  5. Sysdate qui marche pas ??
    Par StouffR dans le forum Langage SQL
    Réponses: 4
    Dernier message: 28/08/2002, 13h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo