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++

  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 : 49
    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 165
    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 165
    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 : 49
    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 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

  6. #6
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    769
    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 : 769
    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.

  7. #7
    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).

  8. #8
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 807
    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 807
    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, ...

  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
    Ben perso, avant la fac, personne ne m'a jamais appris à décomposer un nombre. Certes je savais déjà ce qu'étais une unité, une dizaine, une centaine... mais on m'avait jamais fait utiliser des opérations mathématiques successives (un algo, quoi) pour y arriver.

    Bref, toujours est-il qu'on parle d'un exercice d'algorithmique de base. Effectivement décomposer un nombre chiffre par chiffre est l'un des problèmes mais la solution qu'à posté l'OP semble l'avoir résolu (il y a bien des divisions successives et des modulo pour récupérer le chiffre).
    Le but ici est que les étudiants acquièrent la capacité de découper un problème en sous problèmes puis en lignes de code. Effectivement c'est trivial pour toi et moi... mais pas pour un débutant.

    Je ne connaissais pas les bucket list (enfin pas en tant que patron de conception, j'ai déjà dû en utiliser sans savoir le nom). Ca répond au problème... Pas sûr que l'OP ait les notions nécessaire pour comprendre cette solution néanmoins. Dans notre cas, un simple tableau (même pas en 2 dimensions comme avait proposé l'OP), serait suffisant edit : le tableau en 2 dimensions est l'une des consignes de l'exercice.


    Je fais une aparté. Je communique très peu habituellement, mais ça fait plus de 10 ans que je me rends sur dev.net... et je connaissais bien l'amour des développeurs pour les standards (étant moi-même développeur je les suis de près), mais je suis assez choqué de voir qu'on n'arrive pas à se mettre à la place d'étudiants, de mettre de côté une partie de nos connaissances et notre rigueur, de vulgariser les termes. Bref, de se souvenir de "la base".

  10. #10
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 807
    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 807
    Par défaut
    Citation Envoyé par Trehinos Voir le message
    Je ne connaissais pas les bucket list (enfin pas en tant que patron de conception, j'ai déjà dû en utiliser sans savoir le nom)
    Table de hachage en STL ce sont les conteneurs std::map et std::set même si leur implémentation peut être différente


    Citation Envoyé par Trehinos Voir le message
    Je fais une aparté. Je communique très peu habituellement, mais ça fait plus de 10 ans que je me rends sur dev.net... et je connaissais bien l'amour des développeurs pour les standards (étant moi-même développeur je les suis de près), mais je suis assez choqué de voir qu'on n'arrive pas à se mettre à la place d'étudiants, de mettre de côté une partie de nos connaissances et notre rigueur, de vulgariser les termes. Bref, de se souvenir de "la base".
    Non c'est différent : pour ma part, j'ai fait mes études en DEUG MIAS et licence informatique en 2000 (<- donc ultra générique) et lorsqu'on me donnait un travail c'était l'algorithmie/ les structures de données qui pour moi été un défi à coder le mieux possible (temps de calcul, espace mémoire, ...)

    Là, je vois que ceux qui postent s'en fichent de l'algorithmie (ils n'arrivent pas à cerner le gros du travail) et butent sur des trucs triviaux comme des mathématiques (ici décomposition en base 10) des structures ultra basiques (ici parcours de données contiguës) ... alors leur parler de hachage, d'itérateur et d'arbres informatiques

  11. #11
    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
    Ah oui, ça je connais =P
    Merci de m'avoir répondu... J'avais déjà 6 ans de prog derrière moi quand je suis arrivé à la fac et moi aussi j'optimisais les codes de mes exos. Mais c'était pas le cas de mes camarades qui débutaient...

    Que "ça marche", c'était déjà une grande victoire... Laissons les apprendre les choses dans l'ordre ^^ Déjà ce qu'est un algorithme et comment le penser puis l'exprimer, ensuite l'optimiser.
    Tu connais le credo ^^ : "make it works, then make it right, then make it fast" (critiquable, certes, mais reconnu)

  12. #12
    Invité de passage
    Homme Profil pro
    Développeur Java
    Inscrit en
    Février 2020
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Février 2020
    Messages : 1
    Par défaut
    Tu t'embêtes pour rien, le principe est simple tu prends ton nombre tu le divises par 10 et tu le multiplies par 10 tu retranches cette valeur à ton nombre original et tu as ton digit, tu fais une boucle où tu divises ton nombre original par 10 à chaque étape tu t'arrêtes quand ta valeur est < à 1.


    exemple avec ton nombre 7377680
    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 number = 7377683;
            //nextNumber est à 737768
            int nextNumber = number / 10;
            //currentDigit est à 3 (7377683-737768*10)
            int currentDigit = number - nextNumber*10;
     
            //number est à 737768
            number = nextNumber;
            //nextNumber est à 73776
            nextNumber = number / 10;
            //currentDigit est à 8 737768-(73776*10)
            currentDigit = number - nextNumber*10;
     
     
            //number est à 73776
            number = nextNumber;
            //nextNumber est à 7377
            nextNumber = number / 10;
            //currentDigit est à 6 73776-(7377*10)
            currentDigit = number - nextNumber*10;

  13. #13
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    769
    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 : 769
    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
    [...]

  14. #14
    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
    Citation Envoyé par jo_link_noir Voir le message
    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
    [...]
    Ah ok ^^ Oui j'ai effectivement pris un mauvais exemple dont le problème est plus le typage que le flux. Je croyais que tu me parlait de "mark"er le flux avec la méthode sync()... je comprenais rien xD

  15. #15
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 807
    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 807
    Par défaut
    Citation Envoyé par AsyncCallBack Voir le message
    Tu t'embêtes pour rien, le principe est simple tu prends ton nombre tu le divises par 10 et tu le multiplies par 10 tu retranches cette valeur à ton nombre original et tu as ton digit, tu fais une boucle où tu divises ton nombre original par 10 à chaque étape tu t'arrêtes quand ta valeur est < à 1.
    Et en C++

    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
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    #include <iostream>
    #include <cstdlib>
     
     
    class Generator_Get_Digit {
    private:
     
        typedef unsigned int (Generator_Get_Digit::*t_func_yield) ();
     
    public:
     
        Generator_Get_Digit() { clear(); }
     
    public:
     
        void clear() {
            value           = 0;
            current_val     = 0;
            is_not_finished = false;
            concrete_yield  = &Generator_Get_Digit::yield_noop;
        }
     
        unsigned int get_value() { return value; } // should test is_finished.
     
        void reset(bool input_right_to_left) {
            current_val     = value;
            is_not_finished = true;
     
            if (input_right_to_left) {
                concrete_yield = &Generator_Get_Digit::yield_right_to_left;
            } else {
                concrete_yield = &Generator_Get_Digit::yield_left_to_right;
     
                init_left_to_right();
            }
        }
     
        void reset(unsigned int new_value, bool input_right_to_left) {
            value = new_value;
     
            reset(input_right_to_left);
        }
     
        inline unsigned int yield() { return (this->*concrete_yield) (); }
     
    private:
     
        void init_left_to_right() {
            unsigned int tmp_value = value;
     
            divisor = 1;
     
            while(tmp_value > 9) {
                divisor   *= 10;
                tmp_value /= 10;
            }
        }
     
        unsigned int yield_left_to_right() {
            unsigned int ret;
     
            if (is_not_finished) {
    //          std::cout << "yield_left_to_right - debug : cval: " << current_val << ", div: " << divisor;
     
                if (current_val > 9) {
                    ret = (current_val / divisor);
                    current_val  = (current_val - (ret * divisor));
                    divisor     /= 10;
                } else {
                    ret = current_val;
                    is_not_finished = false;
                }
     
    //          std::cout << ", ret: " << ret << std::endl;
            } else {
    //          std::cout << "yield_left_to_right - debug : EOG" << std::endl;
     
                ret = EOG;
            }
     
            return ret;
        }
     
        unsigned int yield_noop() {
            return EOG;
        }
     
        unsigned int yield_right_to_left() {
            unsigned int ret;
     
            if (is_not_finished) {
    //          std::cout << "yield_right_to_left - debug : cval: " << current_val;
     
                if (current_val > 9) {
                    ret = (current_val % 10);
                    current_val /= 10;
                } else {
                    ret = current_val;
                    is_not_finished = false;
                }
     
    //          std::cout << ", ret: " << ret << std::endl;
            } else {
    //          std::cout << "yield_right_to_left - debug : EOG" << std::endl;
     
                ret = EOG;
            }
     
            return ret;
        }
     
    public:
     
        static const unsigned char EOG; // End Of Generator
     
    private:
     
        unsigned int value;
     
        unsigned int current_val;
        unsigned int divisor;
        bool         is_not_finished;
     
        t_func_yield concrete_yield;
    };
     
    const unsigned char Generator_Get_Digit::EOG = 10;
     
     
    void print_number(Generator_Get_Digit& generator, const std::string& begin_str) {
        std::cout << begin_str << generator.get_value() << std::endl;
     
        unsigned int digit = generator.yield();
     
        while(digit != Generator_Get_Digit::EOG) {
            std::cout << "digit: " << digit << std::endl;
     
            digit = generator.yield();
        }
    }
     
     
    int main()
    {
        Generator_Get_Digit generator;
     
        generator.reset(72481269, true);
     
        std::cout << "value: " << generator.get_value() << std::endl
                  << "1: " << generator.yield() << std::endl
                  << "2: " << generator.yield() << std::endl
                  << "3: " << generator.yield() << std::endl
                  << "4: " << generator.yield() << std::endl;
     
        generator.reset(true); print_number(generator, "\nValue: ");
     
        generator.reset(false); print_number(generator, "\nValue (reverse): ");
     
        generator.reset(1029876, true); print_number(generator, "\nOther Value: ");
     
        generator.reset(false); print_number(generator, "\nSame Value (reverse): ");
     
        generator.reset(8, true); print_number(generator, "\nOther Value: ");
     
        generator.reset(false); print_number(generator, "\nSame Value (reverse): ");
     
     
        return EXIT_SUCCESS;
    }

  16. #16
    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 : 49
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Par défaut
    Beaucoup de messages ...

    Pour répondre, je signalerai qu'en effet l'objectif est le codage de l'algo, pas tellement le C++. Qu'on a pas vraiment "appris" d'ailleurs, on a simplement un petit mémento c++ avec les bases suffisantes pour nous permettre de coder nos algos. (en programmation, on travaille en C#)

    J'utilise Code::Block, que je ne maîtrise pas forcément non plus. Précisons que je suis en 1ère année de BTs au CNED (donc un peu seule...) et....attention je vais vous choquer......je ne suis pas un "il" mais un "elle" (pourtant j'avais choisi un avatar que je croyais assez parlant...).

    Bref. Donc mon problème de boucle infinie, c'était mon tableau, qui n'avait pas assez de cases : quand je déclare
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int tabPosition[9][8] ;
    en fait ça veut dire un tableau de 9 cases de 0 à 8 dans lesquelles il y a 8 cases de 0 à 7. Et non pas de 0 à 9 puis de 0 à 8 comme je le pensais.
    J'étais donc "out of range" sans le comprendre.

    Donc il suffisait de remplacer ça dans mon code, et en effet ça fonctionne...presque.
    Encore quelques petits réglages, déjà en présentation et la reconstitution du nombre qui n'est pas correcte, faut que je bosse dessus, je vais peut-être y arriver.

    Merci à tous pour votre participation (même si, victime de découragement, je reprends seulement aujourd'hui...)

  17. #17
    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 : 49
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Par défaut
    Il me reste une chose tout à fait mystérieuse.
    Ce petit bout de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    for (int chiffre = 0; chiffre <= 9; chiffre ++) {
                k = 0;
                while (tabPosition[chiffre][k] != -1) {
                    cout <<endl << "Calc : " << "nb = "<< nb << " + " << chiffre << " X 10 exp "  << tabPosition[chiffre][k]<< " /Calc "<< endl;
                    nb += chiffre * pow(10,tabPosition[chiffre][k]);
                    k += 1;
                }
            }
            cout << nb;
            cout << endl << "Entrer un nbre entier de 9 chiffres maximum = ";
            cin >> nb;
    Donne ça :
    Nom : Capture poids chiffre.PNG
Affichages : 349
Taille : 11,8 Ko

    Il semble avoir quelques difficultés de calcul Code::Block
    Parce que je suis presque sûre que 1 x 10^2 = 100
    et non pas 99

    Pour certain nombres, il n'y a pas d'erreurs, parfois il y a seulement 1 d'écart, parfois 2 comme ici.

    Si quelqu'un sait d'où ça vient, je serais vraiment curieuse de savoir pourquoi

  18. #18
    Membre Expert
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    737
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 96
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 737
    Par défaut
    Bonjour,

    pow() est censé travailler sur des flottants et tu l'utilises sur des entiers, donc en plus d'une certaine imprécision, il y a une perte d'informations. Si ton compilateur est correctement configuré, il t'a normalement alerté du problème.

    Un peu de lecture sur "le pourquoi du comment" de pow():
    https://code-examples.net/fr/q/f1e074

    Ensuite, dans ton bout de code, si tu regardes de près ton while (...), de la manière dont tu l'utilises, ne remarques-tu pas une certaine similitude avec ce que ferait un for (...) ?

    Pour finir, une petite boucle de saisie simple et didactique :
    https://onlinegdb.com/B1jlx_-4I
    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
    #include <iostream>
     
    using std::cout;
    using std::cin;
     
    int main()
    {
        unsigned long nb= 0;
        while(true){
            cout<< "nb(s)? \n";
            cin>> nb;
            if (cin.fail() or nb==0)
              break;
     
            cout<< "  processing: "<< nb<< '\n';
            //.....
        }
    }
    Bon courage !

  19. #19
    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 : 49
    Localisation : France, Haute Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeuse Freelance

    Informations forums :
    Inscription : Mars 2019
    Messages : 247
    Par défaut
    Super Kaitlyn merci beaucoup

    En effet j'avais pas pensé à un "simple" problème d'arrondi....je ne crois pas que le compilateur m'ait averti, ou alors je ne l'ai pas compris s'il l'a fait
    Je me coucherai moins bête ce soir. J'avais collé des partout pour chercher d'où venait l'erreur, sans trouver.

    Possible que dans ce bout de code la boucle while fasse la même chose qu'une boucle for....sauf qu'on nous apprend à optimiser au maximum nos algorithmes, or dans ce cas la boucle while permet d'arrêter le parcours à la 1ère valeur -1, au lieu de parcourir tout le tableau. Petite économie en terme de temps d'exécution machine.

    Encore merci d'avoir pris le temps de regarder. Vraiment....je n'imaginais pas une telle explication

  20. #20
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 165
    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 165
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par RowanMayfair Voir le message
    Possible que dans ce bout de code la boucle while fasse la même chose qu'une boucle for....sauf qu'on nous apprend à optimiser au maximum nos algorithmes, or dans ce cas la boucle while permet d'arrêter le parcours à la 1ère valeur -1, au lieu de parcourir tout le tableau. Petite économie en terme de temps d'exécution machine.
    Non.
    Ton while n'a aucune raison d'être un while : tu fais une initialisation (de k), un test et une opération de fin de boucle (incrémentation de k), c'est exactement le pattern du for et une boucle for serait bien plus lisible, ne serait-ce que pour limiter la portée de k à la boucle.
    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.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

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

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