Bonjour, je dois créer un batch qui donne ceci :
J'ai trois variables, lorsque la 1ere vaut 1 on addition la 1 et la 3, la 2 et la 3 et la 1 et la 2
si elle vaut 2, même chose sauf que l'on soustrait
si elle vaut 3, même chose avec la multiplication
et enfin si elle vaut 4 c'est une division.
voilà mon code si vous pourriez m'aider à trouver mon erreur.
merci d'avance:
@echo off
cls
echo le paramŠtre 1 est %1
echo le paramŠtre 2 est %2
echo le paramŠtre 3 est %3
echo le paramŠtre 4 est %4
If "<%1>"=="<1>" set /a r=%1+%2
echo paramŠtre 1 + paramŠtre 2 = %r%
set /a r=%2+%3
echo paramŠtre 2 + paramŠtre 3 = %r%
set /a r=%1+%3
echo paramŠtre 1 + paramŠtre 3 = %r%
If "<%1>"=="<2>" set /a r=%1-%2
echo paramŠtre 1 - paramŠtre 2 = %r%
set /a r=%2-%3
echo paramŠtre 2 - paramŠtre 3 = %r%
set /a r=%1-%3
echo paramŠtre 1 - paramŠtre 3 = %r%
If "<%1>"=="<3>" set /a r=%1*%2
echo paramŠtre 1 * paramŠtre 2 = %r%
set /a r=%2*%3
echo paramŠtre 2 * paramŠtre 3 = %r%
set /a r=%1*%3
echo paramŠtre 1 * paramŠtre 3 = %r%
If "<%1>"=="<4>" set /a r=%1/%2
echo paramŠtre 1 / paramŠtre 2 = %r%
set /a r=%2/%3
echo paramŠtre 2 / paramŠtre 3 = %r%
set /a r=%1/%3
echo paramŠtre 1 / paramŠtre 3 = %r%
pause
Le prof m'a dit de faire avec une boucle goto mais je ne vois vraiment pas...
Une question toute bête : quel est l'énoncé ?
PS : ton if n'impacte que le premier "set truc" qui le suit. Il faut malheureusement que utilises le "goto" pour "sauter" les lignes que tu ne veux pas voir s'exécuter.
PS2: C'est ignoble de vous apprendre à programmer avec un langage obligeant à utiliser des "goto" pour conditionner un bloc d'instructions. Rassure-moi, ton prof n'est pas informaticien ?
Ton prof attend certainement ça : https://gist.github.com/2471692
À optimiser de ton côté. ![]()
( virer les gotos
)
Entre autres :
- vérifier qu'il y a trois arguments de passés ;
- vérifier que ces trois arguments sont des entiers.
@Raspberry-Pi :
L'énoncé est dans son premier post.
Et pour info, au lieu d'utiliser un goto, tu peux utiliser des parenthèses dans le cas de figure évoqué, e.g. :
if %1==1 (
...
...
)
DN4
C'est compatible avec les vieilles versions de windows les parenthèses ? C'est bon à savoir. C'est une solution bien plus propre.
DN4
oui ! En effet ça m'a totalement l'air d'être ça merci beaucoup, je vois mon erreur
"- vérifier qu'il y a trois arguments de passés ;
- vérifier que ces trois arguments sont des entiers."
J'utilise des if not pour ça ?
Raspberry-Pi
eh bien faut croire que si, s'en est bien un
@Raspberry-Pi :
Quelles sont les versions de Windows que tu considéres comme vieilles, car c'est vraiment à partir de MS-DOS 3.3 environ que Batch a commencé à relativement servir ?
Le groupement de commandes après une condition faite grâce à la commande IF est apparu sous Windows NT 4, tout comme le switch /A de SET qui est plus qu'utile, donc bon... Je te souhaite bonne chance si tu envisages de créer un script Batch fonctionnel sur toutes les versions de Windows non actuelles.
@CercleVicieux :
Premièrement, décompose la tâche ; ensuite, vois comment tu peux mettre en œuvre chacune des étapes, à partir de tes connaissances, et en faisant des recherches sur les commandes offertes par Batch.
- On doit d'abord récupérer le nombre d'arguments que l'utilisateur a passé au script lors de son exécution. Comment procéder, sachant que Batch ne possède pas de variable spéciale contenant cette information, contrairement à sh(1) par exemple ? Eh bien, on va boucler sur chaque argument, un par un, grâce à la commande FOR et la variable %* qui a pour valeur tout texte se trouvant après le nom du script, qui est lui-même stocké dans %0 (en d'autres termes : "ligne de commandes privée du nom du script"), et au lieu de les afficher, on va simplement incrémenter une variable initialisée à zéro, qui, au final, aura pour valeur le nombre d'arguments total.
Donc notre logique est d'utiliser un compteur auquel on ajoutera 1 à chaque fois que l'on parcourera un nouvel argument.
set argc=0
for %%a in (%*) do set /a argc+=1
Soient %1 = 2 ; %2 = 3 ; %3 = 4.
Au premier tour de boucle, %%a vaudra %1, soit 2, mais cette information ne nous intéresse aucunement. On incrémente argc de 1 ; on a alors argc=1. Ainsi de suite, jusqu'à ce que %%a prenne la valeur contenue dans %3. On se retrouve finalement avec argc=3.
Une fois cela assimilé, je veux bien répondre à la question suivante, que tu as sûrement dû te poser : " Pourquoi deux % sont utilisés et non un seul dans la commande FOR ?
"
Je n'ai pas de longue explication à te donner, c'est juste la syntaxe qui y est comme ça, et pour utiliser la variable ce sera toujours %%a par exemple, qui devra être utilisée. Par contre, il faut bien noter que ceci est vrai dans un script, et non en ligne de commandes, où tu utiliseras %a.
- Ensuite, on doit vérifier que le nombre d'arguments est bel et bien égal à 3. Pour ce faire, on fait appel à la commande IF. Si la condition est remplie, alors l'exécution du script continue. Si la condition n'est pas remplie, alors on en fait part à l'utilisateur.
if %argc% neq 3 (
echo usage: %0 n1 n2 n3
exit /b 1
)
- Maintenant que nous sommes sûrs que trois arguments ont été passés au script, on doit s'assurer d'une dernière chose : est-ce qu'ils sont des nombres, plus particulièrement des entiers, étant donné que Batch n'est pas capable d'opérer sur des nombres décimaux ? Pour cette problématique je me suis arraché les cheveux, car avec une même commande, le résultat retourné différait, on ne sait pourquoi ! Donc ça marchait bien, mais qu'une fois sur deux...
La solution la plus sûre serait de demander à l'utilisateur d'entrer des nombres entiers positifs ou nuls. De mon côté j'ai trouvé des alternatives, mais pas forcément fiables à 100 %, car elles ne traîtent pas certains cas de figure correctement, donc autant se focaliser sur la solution qui fonctionne parfaitement. Tu peux voir l'astuce à la ligne 9 de mon code final.
- Une fois cela fait, il ne faut pas oublier que des divisions peuvent être faîtes, et donc que l'on doit vérifier qu'il n'y a pas de division par zéro. En l'occurence, dans notre cas de figure, on divise le premier paramètre par le second ou troisième ; on doit donc vérifier que, lorsque %1 vaut 1, %2 et %3 soient différents de 0. On fait appel à la commande IF pour tester %1 et la commande FOR pour boucler sur %2 et %3 afin de vérifier si l'un ou l'autre est égal à 0 ; le cas échéant, on prévient l'utilisateur.
Après coup, j'ai remarqué que lorsqu'on fait un simple set /a x=1/0 le message "Erreur de division par zéro" est affiché, mais j'ai quand même laissé la vérification, car dans mon code, lorsque %1 vaut 1 et que %2 ou %3 est égal à 0, on ne procède pas les paramètres suivants, ce qui induit que la boucle FOR ne fait qu'une itération.
Voici le code : https://raw.github.com/gist/2485854/03103714ebd61ff9ba705b02c5fac0ef34e78b15/gistfile1.txt
( Mon premier script en Batch.
)
J'ai apporté des optimisations par rapport à ce que j'ai dit, ainsi que réagencé la structure-même du code. J'ai aussi entièrement revu la logique pour effectuer la partie principale du script. Je pense qu'il est très propre pour un script écrit en Batch.
De plus, si quelqu'un a une solution pour gérer aussi les nombres entiers négatifs, qui le fasse savoir. Le principe est de vérifier que chaque argument est un nombre entier, négatif, nul, ou positif, et non autre chose. ![]()
Je viens de me rendre compte que j'ai fait une erreur, et dans mon code, et dans ma phrase.
Ce n'est pas lorsque %1 vaut 1 que l'on doit vérifier si %2 ou %3 vaillent 0 ou non, mais lorsqu'il est égal à 4.
https://raw.github.com/gist/2485854/b90f9784e29c32491716863261b692b86b0ca64c/gistfile1.txt
WAW man ! Merci mec, mais je demandais pas un truc AUSSI poussé
Pour une première fois tu gère ! Tu as appris tout ça où ? ^^
En fait j'ai pris ton premier code et je l'ai un peu modifié, ça donne ça :
@echo off
cls
if %1==1 goto Add
if %1==2 goto Sous
if %1==3 goto Multi
if %1==4 goto Divis
:Add
set /a r=%1+%3
set /a r=%2+%3
set /a r=%1+%3
goto :add1
:Sous
set /a r=%1-%3
set /a r=%2-%3
set /a r=%1-%3
goto sous1
:Multi
set /a r=%1*%3
set /a r=%2*%3
set /a r=%1*%3
goto :mult1
:Divis
set /a r=%1/%3
set /a r=%2/%3
set /a r=%1/%3
goto :divis1
:add1
echo paramètre 1 + paramètre 3 = %r%
echo paramètre 2 + paramètre 3 = %r%
echo paramètre 1 + paramètre 2 = %r%
goto:eof
:sous1
echo paramètre 1 - paramètre 3 = %r%
echo paramètre 2 - paramètre 3 = %r%
echo paramètre 1 - paramètre 2 = %r%
goto:eof
:mult1
echo paramètre 1 * paramètre 3 = %r%
echo paramètre 2 * paramètre 3 = %r%
echo paramètre 1 * paramètre 2 = %r%
goto:eof
:divis1
echo paramètre 1 / paramètre 3 = %r%
echo paramètre 2 / paramètre 3 = %r%
echo paramètre 1 / paramètre 2 = %r%
goto:eof
pause
ça marche du tonnerre merci encore mec !
Lorsque j'ai posté mon premier post dans ce topic, je ne connaissais absolument rien du Batch, à part les fameux GOTO , évidemment, et le set /a je l'ai découvert dans ton premier post. Je t'ai conseillé d'apporter des améliorations au script sans savoir moi-même comment les mettre en œuvre, ni quels outils utiliser, en sachant que les ajouter rendrait le script plus propre et sécurisé, si bug(s) il y a, ou que l'utilisateur ne fait pas ce qui lui est demandé, c'est-à-dire passer des entiers en tant qu'arguments. Il faut toujours se mettre à la place de l'utilisateur.
C'est pourquoi j'ai entrepris d'apprendre la syntaxe du Batch et le peu de commandes dont il est dôté, afin de pouvoir apporter des solutions au problème tout en découvrant un nouveau langage. En fouillant à droite à gauche j'ai appris des techniques, des astuces, pas forcément en rapport avec le but recherché d'un tel script, mais toutefois enrichissantes, et en même temps ça me faisait lire du code qui, au fur et à mesure devenait de plus en plus compréhensible. Du coup maintenant je connais un nouveau langage de programmation.
Il faut dire aussi que faire le rapprochement entre des techniques que tu connais déjà et d'autres façons de les produire, est bien plus aisé que d'apprendre des notions élémentaires, des mots clés couramment utilisés, ainsi que la syntaxe qui doit être utilisée, le tout confondu.
J'ai appris grâce à différents sites, et surtout en ayant les bons mots clés. Je t'ai fait une liste de tous les liens que j'ai visités, dans l'ordre : https://raw.github.com/gist/2500963/9d15b5f45c95de0d88bc2ea877f79ce0ccd4d178/gistfile1.txt
Si je devais te conseiller un site en particulier, ça serait celui qui a le plus d'occurences dans le lien ci-dessus ( merci awk(1)
), c'est-à-dire la partie concernant les fichiers Batch de robvanderwoude.com : http://www.robvanderwoude.com/batchfiles.php (passe sur le bouton "Batch Files" à gauche pour avoir une liste sympa) ; et http://ss64.com/nt/ pour les récapitulatifs de chaque commande que tu peux consulter via la commande <commande> /? sous CMD.exe.
Concernant le dernier code de posté, non, il ne peut fonctionner correctement, étant donné que tu utilises la variable r pour chaque opération ; tu ne fais que traiter le premier paramètre avec le second, et les trois résultats escomptés seront toujours identiques lors de l'affichage sur la sortie standard, puisque sa valeur initiale sera redéfinie deux fois, à chaque fois qu'il y aura un saut dans le label concerné.
Concrètement, si %* = 1 2 3 , la condition %1==1 sera vérifiée ; un saut vers le label Add se fera donc. Dans cette partie d'instructions, la variable r aura tout d'abord la valeur 1 + 3, soit 4, puis sera redéfinie à 2 + 3, soit 5, et enfin à 1 + 2, soit 3. Un saut sur le label add1 aura lieu.
Ce qui s'affichera alors est :
paramètre 1 + paramètre 3 = 3
paramètre 2 + paramètre 3 = 3
paramètre 1 + paramètre 2 = 3
Ce qui est incorrect.
Il te faut donc utiliser trois variables différentes stockant chacune l'un des différents cas. Tu ne peux pas y échapper... sauf en bouclant trois fois, en redéfinissant la variable contenant les résultats à chaque itération, avec une boucle while faite maison... mais c'est se compliquer la tâche pour rien. ![]()
Merci pour les sites ils vont m'être utiles :D
En effet, c'est une mauvaise habitude que j'ai d'utiliser que la variable r. Merci je corrige ça.
Maintenant j'ai un autre problème.
Je dois entrer un paramètre 1 et 2. Ensuite le batch doit faire la table de multiplication de la première variable jusqu'à la deuxième variable. Je doit utiliser un for. T'as pas une idée pasque je bloque moi :p
voilà mon code :
@echo off
cls
for /l %%a in (0,1,10) do (set /a r=%%a*%1
echo %%a * %1 = %r%)
pause
ça m'affiche le %1 jusqu'à 10 mais pas les réponses.
Petite correction de mon code :
@echo off
cls
for /l %%a in (0,1,%2) do (set /a r=%%a*%1
echo %%a * %1 = %r%)
pause
Maintenant ça m'affiche jusqu'à la deuxième variable définis mais toujours pas de réponse
a
Ouaip, j'ai une petite idée... mais je ne suis pas sûr d'avoir bien compris la consigne.
Les paramètres sont 2 et 4 ; on doit afficher 2 * 0, 2 * 1, 2 * 2, 2 * 3, 2 * 4, ou les tables de multiplication des deux chiffres / nombres ?
Si c'est le premier cas de figure qui est demandé ( ce que tu as fait et qui m'a mis le doute, petit chenapan
), alors rajoute juste la seconde ligne du code ci-dessous avant ta boucle, et utilise !r! au lieu de %r%, car la variable est à chaque fois redéfinie.
Si c'est le second cas, alors regarde ce que j'ai fait.
@echo off
setlocal enabledelayedexpansion enableextensions
:: Ici, on devrait vérifier que deux paramètres sont passés et qu'ils sont des entiers,
:: ainsi que permuter ces derniers si le premier est supérieur au second.
for /l %%i in (%1, 1, %2) do (
for /l %%j in (1, 1, 10) do (
set /a "res = %%i * %%j"
echo %%i x %%j = !res!
)
echo.
)
« [...] ou les tables de multiplication des deux chiffres / nombres ? »
Je voulais pas dire ça...
ou, suivant l'exemple, les tables de multiplication de 2, 3, et 4 ?
Excuse-moi si je n'ai pas été assez clair :P
Eh bien en fait : le %1 représente la table que je veux et le %2 représente le chiffre jusqu'à laquelle je veux qu'il soir multiplié.
Par exemple : en %1 j'ai 5 et en %2 j'ai 10 ça va m'afficher la table de 5 multiplié jusque 10 (5x0=0;5x1=5;...;5x10=50)
C'est plus clair maintenant ?
Donc c'est bien ce que tu as fait. Fait ce que je t'ai dit dans ce cas, i.e., « [...] rajoute juste la seconde ligne du code ci-dessous avant ta boucle, et utilise !r! au lieu de %r%, car la variable est à chaque fois redéfinie. »
Et si tu veux avoir cet affichage en sortie (e.g., 5 * 0, et non 0 * 5), alors tu dois intervertir %%a et %1 sur la ligne du echo dans ton code.