Test de code pour comprendre comportement

Je ne comprends pas le comportement de mon code...

a marqué ce sujet comme résolu.

Bonjour à tous, j’ai fait un petit récapitulatif de code que j’ai écris juste pour comprendre le comportement du code, mais je n’arrive pas très bien à comprendre son comportement est-ce que quelqu’un peut m’aider à comprendre pourquoi il se comporte de cette manière merci ?

Voici le code :

#include <iostream>
#include <vector>
#include <string>

int main()
{
    std::vector <std::string> chaine_Cara{""};
    std::string Texte {""};
    bool vrai{true};

    //std::cout <<"Veuillez entree du texte dans le tableau : ";
    while (vrai == true)
    {

        for (auto const Char : chaine_Cara)
        {
            std::cout <<"Entre Texte : ";
            std::cin >> Texte;
            std::cout <<"Texte entree : " << Char <<std::endl;
        }
    chaine_Cara.push_back(Texte);
    std::cout <<"Texte valider : " << Texte <<std::endl;

    }
    return 0;
}

Peut t’on m’expliqué étape par étape comment se comporte se code Svp ? Merci d’avance bonne soirée/journée.

+0 -0

Salut,

Ce code implémente une logique assez bizarre… :-° Plutôt que t’expliquer point par point ce qui se passe, je pense qu’il serait plus intéressant que tu nous dises :

  • Quel est le comportement que tu cherches à implémenter ?
  • Quel est le comportement que tu attends du code que tu nous donnes ?
  • Quel est le comportement observé et en quoi est-il surprenant à tes yeux ?

Je n’arrive pas à deviner ce que l’auteur de ce code a essayé de faire parce que la logique effectivement implémentée n’a pas trop de sens et il n’y a pas de modification simple qui l’amènerait à un état plus intelligible… Donc en savoir un peu plus sur ce que tu veux faire permettrait de comprendre ce que tu ne comprends pas.

+3 -0

Salut,

Ce code implémente une logique assez bizarre… :-° Plutôt que t’expliquer point par point ce qui se passe, je pense qu’il serait plus intéressant que tu nous dises :

  • Quel est le comportement que tu cherches à implémenter ?
  • Quel est le comportement que tu attends du code que tu nous donnes ?
  • Quel est le comportement observé et en quoi est-il surprenant à tes yeux ?

Je n’arrive pas à deviner ce que l’auteur de ce code a essayé de faire parce que la logique effectivement implémentée n’a pas trop de sens et il n’y a pas de modification simple qui l’amènerait à un état plus intelligible… Donc en savoir un peu plus sur ce que tu veux faire permettrait de comprendre ce que tu ne comprends pas.

adri1

Bonsoir Adri merci pour ta réponse.

en faite je sais que la logique du code est étrange j’essaye juste de comprendre le fonctionnement du code, au début je voulais juste écrire un code qui allait entrer des chaînes de caractères dans un tableau mais je n’ai pas saisi comment faire pour entrer des chaînes de caractères dans un tableau.

Donc j’essaye différente manière en essayant de comprendre ce que je fais.. et la du coup j’ai écrits ce code mais je comprenait pas son comportement et il ne fait pas ce que je lui demande donc du coup j’essayais de comprendre son fonctionnement pour voir pourquoi il agit comme ça et pour bien comprendre la logique de ce code… Mais comme je l’ai mentionné je n’arrive pas à comprendre sont fonctionnement lol…

Pour ce qui est de l’observation de ce code, je me rend compte que quand je compile le code il met une fois sur deux le texte entree au début et après il met les informations que je lui demande mais je n’arrive pas à comprendre pourquoi il saut le chaine_Cara.push_back(Texte) une fois sur deux au début..

Voila j’espère avoir été clair…

+0 -0

Nous non plus, on ne comprends pas trop ce que ton code est censé faire. Il est très bizarre et du coup… on (je!) n’essaie pas.

Reste simple:

  1. choisis comment arrêter la saisie: soit on connait à l’avance le nombre de mots; soit on arrete quand on a un mot vide (pas possible avec std::cin >>; pas possible avec std::getline(std::cin qui n’extrait plus des mots, mais des lignes)
  2. Boucle: sur le nombre de mots attendus ou jusqu’à un mot vide
    • extrait un mot
    • stocke le dans le tableau
std::cout << "combien de mots?"
if (int n ; !(std::cin >> n)) throw...

std::vector<std::string> mots;
for (int i = 0; i < n ; ++i) 
    std::string mot;
    if (!(std::cin >> mot)) throw... // ou arret de la boucle
    mots.push_back(mot); // ou mieux: mots.push_back(move(mot));
}

Nous non plus, on ne comprends pas trop ce que ton code est censé faire. Il est très bizarre et du coup… on (je!) n’essaie pas.

Reste simple:

  1. choisis comment arrêter la saisie: soit on connait à l’avance le nombre de mots; soit on arrete quand on a un mot vide (pas possible avec std::cin >>; pas possible avec std::getline(std::cin qui n’extrait plus des mots, mais des lignes)
  2. Boucle: sur le nombre de mots attendus ou jusqu’à un mot vide
    • extrait un mot
    • stocke le dans le tableau
std::cout << "combien de mots?"
if (int n ; !(std::cin >> n)) throw...

std::vector<std::string> mots;
for (int i = 0; i < n ; ++i) 
    std::string mot;
    if (!(std::cin >> mot)) throw... // ou arret de la boucle
    mots.push_back(mot); // ou mieux: mots.push_back(move(mot));
}

lmghs

Oui j’imagine que vous ne comprenez pas vu que se code n’a pas de logique en lui même c’est juste que j’essaye de comprendre son comportement voir vraiment comment cela fonctionne et pourquoi il me sort un tel résultat afin de bien comprendre le fonctionnement d’un code … vu qu’au départ tout ce que je voulais faire c’est d’entrée une chaîne de caractères dans le tableau.

Par exemple je veux entrée des données string dans le tableau à l’infini ou bien après un nombre de fois, par exemple 10 fois 10 noms différents. sauf que je n’arrive pas à comprendre comment faire pour écrire se code. donc c’est en essayant plusieurs chose que je suis arrivé à écrire se code qui n’a pas de logique, et vu ce qu’il me sort comme comportement j’essayais juste de comprendre pourquoi il agit comme ça…

+0 -0

J’ai peur que tu débutes très mal dans l’apprentissage de la programmation. Il faut lire des tutoriels, des cours, faire les exercices proposés dans les cours, dans l’ordre.

Je sais que ce n’est pas amusant. Mais tenter des trucs un peu au hasard, et voir si ça marche, ça donne des très très mauvais programmeurs. Ca donne des programmeurs qui tentent des trucs au hasard, jusqu’à avoir le résultat attendu.

Catastrophique au final, aussi bien en temps de développement, en terme de performance du programme créé et sur plein d’autres critères.

Je crois que j’ai enfin capté comment tu es arrivé à ce code. Le problème majeur de compréhension se situe dans ce que fait le for (auto const Char : chaine_Cara). J’ai l’impression que tu espères que Char va être une référence mutable vers chaque mot de l’état final du tableau chaine_Cara. En fait, cette boucle itère sur les chaines déjà présentes dans le tableau au moment où elle commence. Évidemment, ça ne fonctionne pas pour remplir les éléments les uns après les autres et le comportement est particulièrement bizarre puisque tu vas demander autant de nouvelles entrées que ce que tu as déjà stocké, et perdre toutes ces entrées sauf la dernière avant de push celle-ci à la fin de chaine_Cara.

J’ai peur que tu débutes très mal dans l’apprentissage de la programmation. Il faut lire des tutoriels, des cours, faire les exercices proposés dans les cours, dans l’ordre.

Je sais que ce n’est pas amusant. Mais tenter des trucs un peu au hasard, et voir si ça marche, ça donne des très très mauvais programmeurs. Ca donne des programmeurs qui tentent des trucs au hasard, jusqu’à avoir le résultat attendu.

Catastrophique au final, aussi bien en temps de développement, en terme de performance du programme créé et sur plein d’autres critères.

elegance

Bonsoir merci mais ce n’est pas du au hasard que j’ai écris ce code c’est en essayant justement de réaliser quelques chose de fonctionnelle je ne code pas au hasard mais vu que je n’arrivais pas au résultat que je voulais je voulais comprendre pourquoi il se comportait comme ça…

PS: je suis le tutoriel de ZesteDeSavoir c++ moderne et j’en suis arrivé au chapitre des tableau au exercices justement, et avant de me lancer dans la réalisation de l’exercices sur l’occurrence j’ai essayé de créer ce code pour pouvoir aller plus loin.

+0 -0

Je crois que j’ai enfin capté comment tu es arrivé à ce code. Le problème majeur de compréhension se situe dans ce que fait le for (auto const Char : chaine_Cara). J’ai l’impression que tu espères que Char va être une référence mutable vers chaque mot de l’état final du tableau chaine_Cara. En fait, cette boucle itère sur les chaines déjà présentes dans le tableau au moment où elle commence. Évidemment, ça ne fonctionne pas pour remplir les éléments les uns après les autres et le comportement est particulièrement bizarre puisque tu vas demander autant de nouvelles entrées que ce que tu as déjà stocké, et perdre toutes ces entrées sauf la dernière avant de push celle-ci à la fin de chaine_Cara.

adri1

Bonsoir Adri, oui tu semble avoir compris comment j’ai fais pour arrivé à se code, par contre je ne comprend pas très bien le fonctionnement de la boucle fort du coup… si j’ai bien compris elle ne boucle pas comme une boucle normal du style (int i{0}; i <10; i++) éléments après éléments, c’est ce que je veux pourtant réaliser, mais par contre je ne comprend pas ton explications sur cette boucle for(auto const Char: chaine_Cara) peut tu stp être un peu plus clair ou me faire un schéma de son fonctionnement, merci.

+0 -0

Cette boucle for parcourt juste les elements de ton vector, donc des string ici. Si tu ecris par exemple :

vector<string> mots { "aaaaa", "bbbbb", "ccccc" };
for (const auto mot: mots) {
    std::cout << mot << std::endl;
}

Ca affiche :

aaaaa
bbbbb
ccccc
+0 -0

Cette boucle for parcourt juste les elements de ton vector, donc des string ici. Si tu ecris par exemple :

vector<string> mots { "aaaaa", "bbbbb", "ccccc" };
for (const auto mot: mots) {
    std::cout << mot << std::endl;
}

Ca affiche :

aaaaa
bbbbb
ccccc

gbdivers

Bonsoir gbdivers, merci pour ta réponse oui je vois … j’ai enfin réussi à faire mon tableau de chaine de caractères mais alors comment je peut le faire avec la boucle for(auto const Char : chaine_Cara) ?

Voici mon code

#include <iostream>
#include <vector>
#include <string>

int main()
{
    std::vector <std::string> chaine_Cara{"Radio"};
    std::string Texte {""};


    while(true){
    for (int i{0}; i < std::size(chaine_Cara); i++)
    {
        std::cout <<"Voici la chaine entree : " << chaine_Cara[i] <<std::endl;


    }
    std::cout <<"Texte entree : ";
    std::cin >> Texte;
    std::cout<<std::endl;
    chaine_Cara.push_back(Texte);
    }

    return 0;
}

Ok j’ai réussi :


int main()
{
    std::vector<std::string> mots { "" };
    std::string Mot{"radio"};

    while(true){
        for (const auto mot: mots) {
        std::cout << mot << std::endl;
        }
    std::cin >> Mot;
    mots.push_back(Mot);
    }
}

Merci à tous pour votre aide :-)

+0 -0

Ton dernier code reste lui aussi bizarre. Pourquoi ajouter au début du tableau un mot vide, et pourquoi initialiser Mot avec un texte qui n’est jamais utilisé? Enlever lignes 4 et 5, les {} et ce qu’il y a dedans serait un code plus "logique".

On peut aussi optimiser les lignes 8 et 12.

int main() {
    std::vector<std::string>  mots;

    for (;;) {
        for ( const auto& mot : mots ) {
            std::cout << mot << '\n';
        }
        flush( std::out );
        std::string  Mot;
        std::cin >> Mot;
        mots.emplace_back( std::move(Mot) );
    }
}

Ton dernier code reste lui aussi bizarre. Pourquoi ajouter au début du tableau un mot vide, et pourquoi initialiser Mot avec un texte qui n’est jamais utilisé? Enlever lignes 4 et 5, les {} et ce qu’il y a dedans serait un code plus "logique".

On peut aussi optimiser les lignes 8 et 12.

int main() {
    std::vector<std::string>  mots;

    for (;;) {
        for ( const auto& mot : mots ) {
            std::cout << mot << '\n';
        }
        flush( std::out );
        std::string  Mot;
        std::cin >> Mot;
        mots.emplace_back( std::move(Mot) );
    }
}

dalfab

Bah je sais pas lol, juste pour le test , ps : je débutes donc normal je fais quelques erreurs de logique …. Par contre je ne connais ni flush ni emplace_black, ni move ni std::out …

+0 -0

Bonsoir à tout ceux qui m’on répondu.

Voici un code que j’ai fait plus propre est-ce qu’il semble plus logique d’après vous ou y à t’il encore des choses qui sont étrange dans se code ?


#include <iostream>
#define NOMINMAX
#include <Windows.h>
#include <vector>

int main()
{
    SetConsoleOutputCP(1252);

    std::vector <double> notes {};
    double Note{0.0};
    int cmp{0};

    std::cout <<"Veuillez entrée des notes dans le tableau : ";

    for(;;){
        std::cin >> Note;

        if (Note < 0)
        {
            break;
        }
        notes.push_back(Note);
    }

    double total{0.0};

    for (auto const NbNote : notes)
    {
        total += NbNote;
        cmp++;
        std::cout <<"TabNote : " << NbNote <<std::endl;
    }

    std::cout <<"Total : " << total / cmp <<std::endl;

    std::vector <std::string> TabMot{};
    std::string Mot{};

    std::cout <<"Veuillez entrée une phrase : ";

    for(;;)
    {

        std::cin >> Mot;
        if (Mot == "Stop")
        {
            break;
        }
        TabMot.push_back(Mot);
    }
    std::cout <<"Voici les phrases entrée dans le tableau : " <<std::endl;
    for (int i{0}; i < std::size(TabMot); i++)
    {
         std::cout << TabMot[i] << " " ;
    }
    
    return 0;
}

Je vous remercie d’avance pour vos retour… Bonne soirée / journée.

+0 -0

Le meilleur critère est de constater que le code fonctionne.

Pourquoi avoir utilisé auto au début et des indices pour la boucle for sur les mots?

Tu fais essentiellement la même chose avec des objets différents.

Personnellement je n’aime pas les boucles infinies du genre:

    for(;;)

Je préfère:

    while(true)
+0 -0

Les boucles infinies pour faire de la lecture… ça me fait froid dans le dos.

Si on rajoute que toute saisie DOIT être vérifiée, cela devient (EDIT: en mode bâclé — je n’ai pas traité les flux fermés, ni les erreurs de type chaines sur entier attendu; mais je ne fais pas semblant de continuer à remplir)

std::string mot;
while ((std::cin >> mot) && mot != "stop")
{
    ...
}

Après on peut détourner le for pour restreindre la portée de la variable mot (et la pollution induite par l’existence d’une variable qui n’a aucun sens hors de la boucle). Tout le monde n’aime pas cette utilisation de for

for (std::string mot ; (std::cin >> mot) && mot != "stop" ; /*rien*/)
{
    ...
}

Autre remarques:

a- localise tes variables au maximum. Est-ce que cmp a un sens alors que tu es en train de saisir les notes? Réponse: non. Donc => ne le déclare pas avant que l’existence de la variable ne soit nécessaire.

b- De plus, ce compteur est redondant. Le nombre d’éléments, c’est notes.size() (ou size(notes) — C++17) => à virer.

c- L’utilisation de {} pour déclarer des variables de type objet non trivial a le don de me faire tiquer au plus au point. Et plus en encore pour les objets qui en vrai contiennent des choses. Je n’ai pas envie de te lancer sur un débat complexe mais en gros et rapidement.

// Je déclare un vecteur vide:
std::vector<type> videaudepart; // pas d'accolade, pas de parenthèse, rien

// Je déclare un vecteur initialisé depuis une expression
std::vector<type> const init_depuis_expr1 = unefonction(); // égal! what else???

// ou carrément, vive auto
auto const init_depuis_expr2 = unefonction(); // plus flexible si le type change
// NB ^-- dans des situations pareilles, il est rare que l'on continue à le modifier ==> const

// Je déclare un vecteur dont je connais les éléments au départ
std::vector const liste_elements {1, 2, 3, 5, 8, 98, 3468, 42}; // accolades!!!
// NB: 
// - pas besoin du type depuis C++17
// - si depuis liste d'éléments, peu probablement que le vecteur change ==> const 
// - Mais il est fort probable qu'il y a erreur de casting et que c'est std::array que l'on voulait utiliser

// Je déclare un vecteur de 42 éléments qui sont des '+'
std::vector quarante_deux_plus(42, '+'); // parenthèses!!!!!

4 façons pour déclarer des vecteurs donc:

  • rien <— vecteur vide
  • égal <— parfait depuis expression
  • {a, b, …} <— liste d’éléments connus
  • (a, b, …) <— utilisation des autres constructeurs.

La version accolades vides pour les conteneurs standards (et autres non agrégats-like -> pas un débat pour un débutant), je trouve ça très maladroit. Et je sais que j’ai des petits camarades qui ne seront pas d’accord.

Les std::string dans tout ça? Tout pareil. Même combat pour moi.

d- Ta dernière boucle pourrait aussi être une for-range loop.

Le meilleur critère est de constater que le code fonctionne.

Pourquoi avoir utilisé auto au début et des indices pour la boucle for sur les mots?

Tu fais essentiellement la même chose avec des objets différents.

Personnellement je n’aime pas les boucles infinies du genre:

    for(;;)

Je préfère:

    while(true)

PierrotLeFou

Bonsoir, Ok pour while(true) j’ai adopté for(;;) car j’avais vu dans un commentaire précédent de quelqu’un qui m’avais répondu qu’il faisais comme ça alors je pensais que c’était peut-être plus approprié donc j’ai adopté cette expression ….

Pour auto et indices sur la boucle for, je ne sais pas pourquoi j’ai eu un petit soucis pour utilisé la boucle auto donc j’ai utilisé les indices du coup….

+0 -0

Les boucles infinies pour faire de la lecture… ça me fait froid dans le dos.

Si on rajoute que toute saisie DOIT être vérifiée, cela devient (EDIT: en mode bâclé — je n’ai pas traité les flux fermés, ni les erreurs de type chaines sur entier attendu; mais je ne fais pas semblant de continuer à remplir)

std::string mot;
while ((std::cin >> mot) && mot != "stop")
{
    ...
}

Après on peut détourner le for pour restreindre la portée de la variable mot (et la pollution induite par l’existence d’une variable qui n’a aucun sens hors de la boucle). Tout le monde n’aime pas cette utilisation de for

for (std::string mot ; (std::cin >> mot) && mot != "stop" ; /*rien*/)
{
    ...
}

Autre remarques:

a- localise tes variables au maximum. Est-ce que cmp a un sens alors que tu es en train de saisir les notes? Réponse: non. Donc => ne le déclare pas avant que l’existence de la variable ne soit nécessaire.

b- De plus, ce compteur est redondant. Le nombre d’éléments, c’est notes.size() (ou size(notes) — C++17) => à virer.

c- L’utilisation de {} pour déclarer des variables de type objet non trivial a le don de me faire tiquer au plus au point. Et plus en encore pour les objets qui en vrai contiennent des choses. Je n’ai pas envie de te lancer sur un débat complexe mais en gros et rapidement.

// Je déclare un vecteur vide:
std::vector<type> videaudepart; // pas d'accolade, pas de parenthèse, rien

// Je déclare un vecteur initialisé depuis une expression
std::vector<type> const init_depuis_expr1 = unefonction(); // égal! what else???

// ou carrément, vive auto
auto const init_depuis_expr2 = unefonction(); // plus flexible si le type change
// NB ^-- dans des situations pareilles, il est rare que l'on continue à le modifier ==> const

// Je déclare un vecteur dont je connais les éléments au départ
std::vector const liste_elements {1, 2, 3, 5, 8, 98, 3468, 42}; // accolades!!!
// NB: 
// - pas besoin du type depuis C++17
// - si depuis liste d'éléments, peu probablement que le vecteur change ==> const 
// - Mais il est fort probable qu'il y a erreur de casting et que c'est std::array que l'on voulait utiliser

// Je déclare un vecteur de 42 éléments qui sont des '+'
std::vector quarante_deux_plus(42, '+'); // parenthèses!!!!!

4 façons pour déclarer des vecteurs donc:

  • rien <— vecteur vide
  • égal <— parfait depuis expression
  • {a, b, …} <— liste d’éléments connus
  • (a, b, …) <— utilisation des autres constructeurs.

La version accolades vides pour les conteneurs standards (et autres non agrégats-like -> pas un débat pour un débutant), je trouve ça très maladroit. Et je sais que j’ai des petits camarades qui ne seront pas d’accord.

Les std::string dans tout ça? Tout pareil. Même combat pour moi.

d- Ta dernière boucle pourrait aussi être une for-range loop.

lmghs

Bonjour, merci pour votre retour… mais Pq faire while(std::cin » mot) ? N’est-ce pas juste pour tester si une chaine de caractères est entrée dans un int au lieu d’un entier ?

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte