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 :

Une boucle infinie : j'ignore pourquoi


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Par défaut Une boucle infinie : j'ignore pourquoi
    Bonjour,

    Je suis en train de m'arracher les cheveux (et c'est dommage quand même ) sur ce petit programme :
    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
    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
    #include <iostream>
    #include <math.h>
     
    using namespace std;
     
    int main()
    {
        unsigned long int nb;
        int tabPosition[9][8] ;
        int position = 0;
        int chiffre,k;
     
        cout << "Entrer un nombre entier de 9 chiffre maxi = ";
        cin >> nb;
     
        while (nb != 0) {
            for (int chiffre = 0; chiffre <= 9; chiffre++) {
                for (int k = 0; k <= 8; k++) {
                    tabPosition[chiffre][k] = -1;
                }
            }
            while (nb != 0) {
                chiffre = nb % 10;
                k = 0;
                while (tabPosition[chiffre][k] != -1 && k < 9) {
                    k += 1;
                }
                tabPosition[chiffre][k] = position;
                nb = nb / 10;
                position += 1;
            }
            for (int chiffre = 0; chiffre <= 9; chiffre ++) {
                if (tabPosition[chiffre][0] != -1) {
                    cout << chiffre << " : ";
                    k = 0;
                    while (tabPosition[chiffre][k] != -1 && k < 10) {
                        cout << tabPosition[chiffre][k] << " ";
                        k += 1;
                    }
                }
            }
            // reconstitution du nbre :
            for (int chiffre = 0; chiffre <= 9; chiffre ++) {
                k = 0;
                while (tabPosition[chiffre][k] != -1) {
                    nb += chiffre * pow(10,tabPosition[chiffre][k]);
                    k += 1;
                }
            }
            cout << nb;
            cout << endl << "Entrer un nbre entier de 9 chiffres maximum = ";
            cin >> nb;
        }
        return 0;
     
    }
    Il s'agit d'un exercice d'algo.
    Il boucle dès le départ, c'est à dire que le programme me demande bien de saisir un nombre et... c'est tout...le voilà parti je ne sais où. Alors que c'est des boucles for

    Une âme charitable pour m'indiquer ce que j'ai mal fait ?

    D'avance merci

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    En dehors du cin et cout, ce code est du C.
    Tu masques des variables de partout, tu dépasses chaque borne de tableau, ce truc va au mieux tomber en marche.
    Et vue la manipulation des compteurs qui partent dans tous les sens, la lisibilité est faible et donne peu envie de s'y pencher.
    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.

  3. #3
    Membre expérimenté Avatar de Trehinos
    Homme Profil pro
    Analyste développeur PHP
    Inscrit en
    Novembre 2012
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Analyste développeur PHP
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2012
    Messages : 100
    Par défaut
    Le problème, c'est que cin est pas vraiment fait pour lire dans une boucle... mais ça peut se faire.

    C'est là :
    Code CPP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    // reconstitution du nbre :
    for (int chiffre = 0; chiffre <= 9; chiffre ++) {
        k = 0;
        while (tabPosition[chiffre][k] != -1) {
            nb += chiffre * pow(10,tabPosition[chiffre][k]);
            k += 1;
        }
    }
    cout << nb;
    cout << endl << "Entrer un nbre entier de 9 chiffres maximum = ";
    cin >> nb;

    Il suffit d'ajouter un juste avant le dernier cin de la boucle, sinon il ne relira jamais l'entrée utilisateur.
    Plus d'infos : http://www.cplusplus.com/forum/beginner/169496/



    Sinon, comme le dit @Bousk, std:array/vector plutôt que des tableaux si c'est du C++.
    Et penser modulaire : l'opération tabPosition, notamment devrait être refactorisée en une fonction puisqu'elle est effectuée plusieurs fois. Ca diminue les copier-collé, c'est plus lisible et plus simple à maintenir/modifier

  4. #4
    Membre éclairé Avatar de RowanMayfair
    Femme Profil pro
    Développeuse Freelance
    Inscrit en
    Mars 2019
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 48
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Par défaut
    désolée si c'est pas clair du tout.
    C'est sans doute parce que ce n'est pas clair pour moi, j'ai du mal à comprendre l'algo, et encore plus de mal à comprendre la correction.
    Je me suis dit que si j'arrivais à coder la correction, ce serait peut-être + clair.

    Le but du truc c'était ça :
    Le but est de créer un programme qui permet de saisir un nombre entier naturel et qui affiche le ou les poid(s) de chaque chiffre dans ce nombre. À partir de ces informations (les poids de chaque chiffre), le nombre doit pouvoir être reconstitué.
    Le poids représente la position du chiffre dans le nombre, en partant de la droite (le premier chiffre de droite est à la position 0, il a donc un poids 0).
    Exemple :
    Si le nombre saisi est :
    7377683
    L’affichage doit donner :
    3 : 0 5
    6 : 2
    7 : 3 4 6
    8 : 1
    7377683
    Explication : le 3 a pour poids 0 et 5 (car on le retrouve à la position 0 et à la position 5 du nombre, en partant de la droite), le 6 a pour poids 2, le 7 à pour poids 3, 4 et 6, et le 8 a pour poids 1. Vous ne devez pas afficher les chiffres qui n’apparaissent pas. Verticalement, les premiers chiffres doivent être dans l'ordre croissant. Horizontalement, les positions doivent aussi être dans l'ordre croissant. Pour mémoriser les poids de chaque chiffre, vous devez utiliser un tableau à 2 dimensions. L’affichage final (7377683) provient de la reconstitution du nombre à partir des poids de chaque chiffre.
    On prendra pour hypothèse que le nombre saisi ne dépasse pas 9 chiffres (inutile de faire un contrôle de saisie). En C++, vous déclarerez ce nombre en "unsigned long int". Attention, le nombre reconstitué doit être aussi en 'unsigned long int". Vous n’avez pas l’autorisation d’utiliser des variables autres que numériques pour gérer ce programme.
    Le programme doit fonctionner pour plusieurs nombres : l’arrêt du programme se fera lorsque le nombre saisi sera égal à 0.
    Je n'ai donc pas réussi à le faire.

    Bon c'est pas grave. Je vous ait mis l'énoncé pour le cas où l'un d'entre vous a envie de se casser un peu la tête

    Moi je vais un peu laisser tomber. C'est très frustrant de ne pas comprendre. Ou j'essaierai..à ma façon, c'est à dire de manière un peu moins "compacte".

  5. #5
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 759
    Par défaut
    Citation Envoyé par Trehinos Voir le message
    Le problème, c'est que cin est pas vraiment fait pour lire dans une boucle...
    Si. Le poste avec sync() présente une mauvaise solution au problème, sans corriger le problème qui est que name est un int plutôt qu'un std::string (seconde réponse du poste). Mettre mark dans un int ne va avoir qu'un effet: rendre invalide le flux. Toute opération sur un flux invalide ne fait rien jusqu'à ce que clear() ou autre fonction de réinitialisation soit utilisée. Il y a plusieurs entrées sur le sujet dans la FAQ.

    Je n'ai pas regardé l'algo en lui-même, mais il faudrait déjà corriger les boucles. N'importe quel outil de debug devrait hurler. for (int chiffre = 0; chiffre <= 9; chiffre++) est faux, il y a un dépassement de tableau. 0 à 9 inclut donne 10 valeur, or, il n'y a que 9 valeurs. Les conditions usuelles utilisent <, mais les boucles sur intervalles seront probablement un bien meilleurs choix.

  6. #6
    Membre expérimenté Avatar de Trehinos
    Homme Profil pro
    Analyste développeur PHP
    Inscrit en
    Novembre 2012
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Analyste développeur PHP
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2012
    Messages : 100
    Par défaut
    Ok merci pour l'éclaircissement sur le cin. Même si je comprends pas ce que tu veux dire par "mark". La doc n'y fait pas référence http://www.cplusplus.com/reference/i.../istream/sync/...

    EDIT : cette doc est plus claire mais toujours pas de "mark"... https://en.cppreference.com/w/cpp/io/basic_istream/sync

    La difficulté ici, c'est que l'énoncé précise bien qu'on ne peut pas utiliser d'autre type que des int (enfin c'est écrit "numérique" mais je vois pas à quoi servirait un float de toutes façons), donc pas de std::string (ni même de char*). Un std::string, c'est sûr ça arrangerait pas mal de problème, notamment celui des boucles et des divisions successives.

    Effectivement toutes les boucles for sont fausses...


    L'OP est étudiant(e). Elle a vu d'autres langages, va certainement en voir d'autres. Ici, il ne s'agit pas de faire du C++ standard, mais de comprendre le problème et d'écrire un algorithme capable d'affecter un poids crossant aux chiffres du nombre de la droite vers la gauche. Donc on oublie la bibliothèque standard et C++20, 17, 14 (ça ne suivrai pas les consignes).

  7. #7
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 757
    Par défaut
    Citation Envoyé par Trehinos Voir le message
    La difficulté ici, c'est que l'énoncé précise bien qu'on ne peut pas utiliser d'autre type que des int
    ....
    Ici, il ne s'agit pas de faire du C++ standard, mais de comprendre le problème et d'écrire un algorithme capable d'affecter un poids crossant aux chiffres du nombre de la droite vers la gauche.
    Si tu es à la faculté et incapable de décomposer un nombre dans une base 10 retourne en 6ième.

    Et non la difficulté c'est de coder des "bucket list" (lien wiki en anglais qui en parle)
    En C, cela correspond à un tableau de listes chaînées, ou éventuellement à un arbre binaire avec comme feuille des tableaux.
    En C++ cela peut être intéressant de mettre en place cette structure : recherche d'une valeur, récupération des poids, ...

  8. #8
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 759
    Par défaut
    Citation Envoyé par Trehinos Voir le message
    Ok merci pour l'éclaircissement sur le cin. Même si je comprends pas ce que tu veux dire par "mark".
    C'est dans l'exemple donné par l'OP sur cplusplus.com:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    [...]
    What's the name of your #1 sibling?
    mark
    [...]

  9. #9
    Membre expérimenté Avatar de Trehinos
    Homme Profil pro
    Analyste développeur PHP
    Inscrit en
    Novembre 2012
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Analyste développeur PHP
    Secteur : Distribution

    Informations forums :
    Inscription : Novembre 2012
    Messages : 100
    Par défaut
    Fais référence à un commentaire effacé : Mais, si j'ai bien compris, c'est une étudiante qui demande de l'aide, les gars... Pas un pro à qui il s'agit de faire la leçon...
    Evidemment ce code est refactorisable et pas pro, mais bon sang, vous écriviez du code parfaitement clair et qui suit les standard dès vos premiers écrits ?


    @RowanMayfair, fait juste un cin.sync() avant ton dernier cin. La boucle devrait arrêter d'être infinie... J'ai pas la patience de refaire ton exo, mais à partir de là tu devrais déjà pouvoir un peu bidouiller

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

Discussions similaires

  1. Réponses: 18
    Dernier message: 26/04/2006, 11h39
  2. Une boucle infinie crontab
    Par tsing dans le forum Administration système
    Réponses: 10
    Dernier message: 10/04/2006, 10h28
  3. Select qui fais une boucle infinie
    Par MaitrePylos dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 28/03/2006, 17h29
  4. Réponses: 10
    Dernier message: 24/12/2005, 15h35
  5. [FTP] comment corriger une boucle infinie ?
    Par sofybj dans le forum Langage
    Réponses: 8
    Dernier message: 08/11/2005, 14h49

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