Que pensez-vous de ce bout de code en C++

Le problème exposé dans ce sujet a été résolu.

Bonjour à vous, depuis quelques temps je m’amuse à afficher un message différent selon ce que l’utilisateur à saisie dans le clavier.

Question : Est-ce une bonne pratique d’écrire de tels codes ? ( ici je parle de différencier les messages en fonction de ce qu’il rentre dans le clavier, il se peut qu’il ait un problème là où on ne se doute point)

code 1 :

#include <iostream> #include <vector>

int main () { std::cout « "Entre le nombre d’element(s) du tableau de notes : "; int elements { 0 };

while (!(std::cin >> elements) or (elements < 0))
{
    if (elements < 0)
    {
        std::cout << "Nombre negatif entre, re-saisir le nombre d'elements du tableau de notes : ";
    }
    else if (!(std::cin >> elements))
    {
        std::cout << "Entre invalide (autre chose qu'un nombre), re-saisir le nombre d'elements du tableau de notes : ";
        std::cin.clear();
        std::cin.ignore(500, '\n');
    }
}

std::cout << "OK" << std::endl;
return 0;

}

ou bien

code 2 :

#include <iostream> #include <vector>

int main () { std::cout « "Entre le nombre d’element(s) du tableau de notes : "; int elements { 0 };

while (!(std::cin >> elements) or (elements < 0))
{
    if (elements < 0)
    {
        std::cout << "Nombre negatif entre, re-saisir le nombre d'elements du tableau de notes : ";
    }
    else if (!(std::cin >> elements))
    {
        std::cout << "Entre invalide (autre chose qu'un nombre), re-saisir le nombre d'elements du tableau de notes : ";
    }

    std::cin.clear();
    std::cin.ignore(500, '\n');
}

std::cout << "OK" << std::endl;
return 0;

}

Remarque personnel : Dans le premier bout de code, à chaque fois que l’utilisateur entre un nombre négatif, ce dernier est toujours présent dans le buffer. Alors que dans le code 2 : les caractères précédemment mémorisés (même les nombres négatifs précédemment entrés sont ignorés :le buffer est vidé a chaque fois). Est ce que je me trompe ? Et lesquels de ces deux codes vaut mieux que l’autre ?

Peut-il y avoir un débordement du buffer si l’utilisateur saisie indéfiniment des nombres négatifs (dans le code 1) jusqu’à que le buffer soit plein.

Et Pourquoi dit-on que rien n’est infinie en informatique lorsque l’on parle des boucles infinies ? (un peu perdu sur ce coup)

J’espère été très concis sur mes propos.

+0 -0

Je suis pas fan du tout de :

while (!(std::cin >> elements) or (elements < 0))

Utilise plutôt std::cin.fail(). L’utilisation de or me déroute un peu mais pourquoi pas.

Pourquoi 500 caractères uniquement ? Si tu veux t’assurer de vider le buffer, vide la taille du buffer.

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

Utilise les balises de code ou indente tes codes d’un niveau supplémentaire afin de mieux le coloré, une bonne partie du code est illisible.

+1 -0

Peut-il y avoir un débordement du buffer si l’utilisateur saisie indéfiniment des nombres négatifs (dans le code 1) jusqu’à que le buffer soit plein.

Non non, le buffer ne va pas débordé. Ne t’inquiète pas, c’est bien codé.

Et Pourquoi dit-on que rien n’est infinie en informatique lorsque l’on parle des boucles infinies ? (un peu perdu sur ce coup)

J’espère été très concis sur mes propos.

Les boucles infinies, c’est assez inutile. Il faut s’assurer que ton programme en sorte au bout d’un moment sinon l’utilité est assez faible. Et à part les boucles infinies, rien n’est infini en informatique. La mémoire est fini, la capacité de calcule est fini, le nombre de valeur que peut représenter un int est fini, … Même si on a beaucoup de ressources, il faut se souvenir que ses ressources sont quand même finies.

Edit: Pardon pour le double post, je pensais édité, j’ai pas fait gaffe.

+1 -0

J’ai lu ceci sur un tuto : […]fail() : retourne true s’il y a eu une erreur sur le flux ou que la dernière opération a échouée, false dans le cas contraire[…] donc si bad() retourne true alors fail() retourne true aussi mais si bad retourne false, fail() peut retourner true[…]

Ce que je ne comprends pas : […] ou que la dernière opération a échouée ?

Et ce quoi la différence entre fail() et bad() ? (désolé si je demande parfois du plat tout cuit sans se rendre compte)

Quel fichier dois-je inclure pour utiliser : std::numeric_limits<std::streamsize>::max()

Pas de souci pour le double post, merci pour ces précisions

+0 -0

Coucou \o

J’avais loupé tes réponses.

fail indique une errreur à gérer alors que bad indique une erreur grave dont on ne peut s’occuper. Lorsque le stream est bad alors il n’est plus utilisable du tout alors que si c’est juste fail, c’est que la précédente lecture a rencontré une erreur et qu’il faut la traiter.

Je t’invite à voir la documentation de basic_istream pour plus d’info sur std::cin.

+1 -0

Je suis pas fan du tout de :

while (!(std::cin >> elements) or (elements < 0))

Utilise plutôt std::cin.fail().

ache

Mais pourquoi donc utiliser .fail() ici? Il faut d’abord tenter la lecture pour se faire jeter, on ne peut pas commencer avec un .fail(). Après, dans le test interne pour distinguer les cas flux fermé VS flux incompatible avec ce que l’on cherche à extraire VS mauvaise borne, .fail() est mieux.

D’où le code que j’avais mis dans la FAQ: https://cpp.developpez.com/faq/cpp/?page=Manipulation-de-la-console#Comment-verifier-les-valeurs-saisies-avec-cin

Je suis pas fan du tout de :

while (!(std::cin >> elements) or (elements < 0))

Utilise plutôt std::cin.fail().

ache

Mais pourquoi donc utiliser .fail() ici? Il faut d’abord tenter la lecture pour se faire jeter, on ne peut pas commencer avec un .fail(). Après, dans le test interne pour distinguer les cas flux fermé VS flux incompatible avec ce que l’on cherche à extraire VS mauvaise borne, .fail() est mieux.

À la base, c’était surtout car il l’utilisait 2 fois, et donc qu’il allait devoir utiliser fail. Mais en vrai. Vous trouvez vraiment que :

while (!(std::cin >> elements) or (elements < 0))

Est plus lisible que :

std::cin >> elements;
while (!std::cin.fail() or elements < 0)

?

La deuxième version est bien plus simple à lire AMHA, même pour quelqu’un qui ne fait pas de C++. D’ailleurs pourquoi utiliser ! si on utilise or ?

std::cin >> elements;
while (not std::cin.fail() or elements < 0)
+0 -0

La 2e version n’est équivalente que si elle est en vrai:

std::cin >> elements;
while (not std::cin.fail() or elements < 0)
{
    ....
    std::cin >> elements;
}

Et donc oui, je trouve la première version bien plus propre. .fail(), .eof() sont très simples à mal utiliser. Beaucoup les ont d’ailleurs mal enseignés. Au point, que dans les conditions des boucles, ils ne sont pour moi pas idiomatiques du C++ — ils n’y sont que sources de bugs.

Pour ce qui est d’être parlante, il faut juste apprendre à la lire: tant que j’arrive à extraire elements de cin.

La 2e version n’est équivalente que si elle est en vrai:

std::cin >> elements;
while (not std::cin.fail() or elements < 0)
{
    ....
    std::cin >> elements;
}

Oui biensûr, ça rajoute un peu de redondance.

+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