Je voulais revivre la nostalgie des bons vieux dos.
J'ai testé quelques commandes batch, mais j'ai remarqué que / a
n'est pas utilisable dans dos.
Existe-t-il une autre méthode que je peux utiliser pour ajouter deux variables sans inclure /a
?
@echo off ::this is how I would originally add two numbers set /p number1= set /p number2= set /a "number1=number1+number2" echo %number1% pause >nul exit
dos states "commutateur invalide. - / a" code > quand j'exécute ce programme.
3 Réponses :
Si vous essayez de le faire à partir du DOS réel (et non de l'émulation de Windows de l'ère 32 bits), ce n'est tout simplement pas possible, à moins que vous ne gériez manuellement chaque paire de nombres possible que vous pourriez avoir en entrée (ce qui devient ingérable lorsque vous dépassez les chiffres à un seul chiffre).
Il s'agissait toujours d'une grande carence dans les fichiers batch de DOS, qui était généralement corrigée en appelant de petits scripts dans des langages de script réels (tels que BASIC), souvent écrits par le même fichier .bat qui les appelait. Ceci, bien sûr, nécessite d'avoir un interprète pour la langue de votre choix.
IMHO une "réponse" qui indique "vous ne pouvez pas faire ça" n'est pas une bonne réponse, à peine un commentaire ... :(
@Aacini "Votre problème n'a pas de solution" est la meilleure solution possible ici. Les commentaires ne sont pas destinés à durer (la politique a toujours été qu'ils peuvent être supprimés à tout moment, même s'ils ne le sont généralement pas), et "vous ne pouvez pas faire cela" est vraiment la réponse ici . En particulier, étant donné que nous parlons d'un système d'exploitation qui a été abandonné il y a plus de deux décennies, la réponse ne changera pas, et donc "vous pouvez le faire" n'est pas seulement la seule réponse valable maintenant, mais la seule réponse valable pour toujours. "Aucune solution" est une réponse; c'est complètement différent de «je ne sais pas» ou de «non recommandé».
C'est aussi proche que possible. Étant donné que le script principal est appelé sum.bat
fournissez les deux nombres comme arguments de ligne de commande.
Voici le code de sum.bat
:
>>> sum.bat 1 0 19 bytes >>> sum.bat 3 6 9 bytes >>> sum.bat 2 ERROR: to few arguments! >>> sum.bat 1 0 19 bytes >>> sum.bat 13 4 ERROR: unexpected argument!
Voici le code de la sous-routine sum-sub.bat
:
@echo off rem // Jump to correct entry point to create/append a list with correct length: 2> nul goto :$%1 & < nul find "" & >&2 echo ERROR: unexpected argument! rem // Do not add anything to the list upon errors: goto :$0 rem /* Inverse list to add as many space-separated `#` symbols as given by the argument; rem extend it in the same manner in order to support numbers greater than `12`: */ :$12 set LIST=%LIST% # :$11 set LIST=%LIST% # :$10 set LIST=%LIST% # :$9 set LIST=%LIST% # :$8 set LIST=%LIST% # :$7 set LIST=%LIST% # :$6 set LIST=%LIST% # :$5 set LIST=%LIST% # :$4 set LIST=%LIST% # :$3 set LIST=%LIST% # :$2 set LIST=%LIST% # :$1 set LIST=%LIST% # :$0
Voici quelques utilisations exemples:
@echo off & > nul ver rem // Define constants here: set SUB=.\sum-sub.bat set FILE=.\sum.tmp set RESULT=.\sum-res.tmp rem // Check if enough arguments are provided: if "%2"=="" (>&2 echo ERROR: too few arguments!) & < nul find "" & goto :END rem // Initialise variables: set LIST= rem // Create list of as many space-separated `#` symbols as given by 1st number: call %SUB% %1 rem // Append list by as many space-separated `#` symbols as given by 2nd number: call %SUB% %2 rem // Terminate execution in case of unsupported numbers: if ErrorLevel 1 goto :END rem // Create empty temporary file: > nul copy /Y nul %FILE% rem // Fill temporary file with as many bytes as list items are given: for %%I in (%LIST%) do (> nul copy /B %FILE% + nul %FILE% /A) rem // Get size of temporary file, filter out first summary line and store in file: dir /A:-D /-W /-C %FILE% | find "1 File(s)" > %RESULT% rem /* Read from file the summary line but display it without "1 File(s)" prefix; rem since this is searched literally, the code becomes language-dependent; rem the "bytes" suffix unfortunately remains: */ < %RESULT% ( for %%I in (# # # # # # # # # # # # # # # # # # # # # # # #) do > nul pause sort & echo/ ) rem // Clean up temporary files: del %FILE% %RESULT% :END
Je dois admettre que j'ai testé cette approche dans l'invite de commande Windows avec les extensions de commande désactivées mais pas dans un véritable environnement MS-DOS.
Je ne pense pas que lang-dos
soit une langue connue que le prettifier de code prend en charge. Dans tous les cas, il ne met pas correctement en évidence votre code, donc je pense que vous seriez mieux avec lang-none
.
@RossRidge, lang-dos
ou lang-cmd
semble reconnaître quelques commandes; mais la principale raison pour laquelle je l'utilise est la mise en évidence des "chaînes" et // des remarques, ce que je trouve assez pratique ...
@RossRidge lang-dos
n'est en effet pas pris en charge, ce qui lui permettra d'utiliser le surligneur par défaut Y a-t-il une coloration syntaxique pour les opérations de ligne de commande DOS ou les fichiers batch DOS? . lang-vb
ou parfois lang-bash
est un meilleur choix pour les fichiers batch
C'est un peu plus délicat que d'utiliser set / a
, mais cela peut être résolu avec MS-DOS 6.22.
Une partie consiste à écrire une fonction pour ajouter des chiffres uniques et une fonction qui peut ajouter plusieurs chiffres.
Le principal problème est de diviser un nombre en un seul chiffre, car MS-DOS ne prend pas en charge la manipulation de chaînes.
Mais il existe un petit défaut dans la gestion de FOR-Loop, /
divise un texte en trois parties.
set var=content set indirect=var > temp$$$.bat echo set result=%%%indirect%%% call temp$$$.bat echo result=%result%
Sorties
FOR %%a in (1 2 3 ) do CALL %0 :myFunc %%a
Avec cette astuce, un nombre peut être divisé en un seul chiffre
split.bat
FOR %%a in (1 2 3 ) do ( set concat=%%a echo %concat% )
Et le add.bat ressemble à
FOR %%P in (/%1) do IF %%P==: goto %1 ... REM This calls the current batch file and jumps to a label CALL %0 :myLabel arg1 ... :myLabel echo arg1=%2 echo Action1 echo Action2 goto :eof
Testé avec succès sur un MS-DOS 6.22 (VMWare)
IF
ne prend pas en charge ELSE
Solution de contournement :
IF %1==b echo It is equal IF NOT %1==b echo It isn't equal
Seul goto
peut accéder à une étiquette, CALL
ne peut démarrer qu'un autre lot.
Solution de contournement :
Mettez quelque chose comme ça dans la première ligne de votre lot
@echo off for %%P in (/%1.) do if %%P==: goto %1 call splitt _valueRev1 %1 call splitt _valueRev2 %2 set _result= set _carry= for %%d in(%_valueRev1_comma%,0,0,0,0,0) do call %0 :getDig1 %%d REM Remove leading zeros :zeroLoop for %%z in (/%_result%) do set _remain=%%z if not %_result%==0%_remain% goto :finish set _result=%_remain% goto :zeroLoop :finish echo %1+%2=%_result% REM Clear temp vars FOR %%v in (_result _carry _len _digit1 _digit2 _remain _valueRev1 _valueRev1_comma _valueRev2 _valueRev2_comma) do set %%v= goto :eof :getDig1 set _digit1=%2 set _digit2= for %%d in (/%_valueRev2%0) do call %0 :getDig2 %%d set _len=%_carry% call %0 :lenAddDigit %_digit1% call %0 :lenAddDigit %_digit1% call %0 :len2val set _result=%_val%%_result% goto :eof :getDig2if not "%_digit2%"==" set _valueRev2=%2 if "%_digit2%"=="" set _digit2=%2 goto :eof :lenAddDigit if %2==1 set _len=%_len%# if %2==2 set _len=%_len%## if %2==3 set _len=%_len%### if %2==4 set _len=%_len%#### if %2==5 set _len=%_len%##### if %2==6 set _len=%_len%###### if %2==7 set _len=%_len%####### if %2==8 set _len=%_len%######## if %2==9 set _len=%_len%######### goto :eof :len2val set _carry= set _val= if %_len%.==. set _val=0 if %_len%.==. goto :eof if %_len%==# set _val=1 if %_len%==## set _val=2 if %_len%==### set _val=3 if %_len%==#### set _val=4 if %_len%==##### set _val=5 if %_len%==###### set _val=6 if %_len%==####### set _val=7 if %_len%==######## set _val=8 if %_len%==######### set _val=9 if NOT "%_val%"=="" goto :eof set _carry=# ########## if %_len%==########## set _val=0 if %_len%==########### set _val=1 if %_len%==############ set _val=2 if %_len%==############# set _val=3 if %_len%==############## set _val=4 if %_len%==############### set _val=5 if %_len%==################ set _val=6 if %_len%==################# set _val=7 if %_len%==################## set _val=8 if %_len%==################### set _val=9 goto :eof :eof
Aucun bloc de code, comme
@echo off for %%P in (/%1.) do if %%P==: goto %1 set _idx= set _remain= set _splitRev= set _splitRev_comma= :loop set _loop=1 for %%a in (/%_remain%) do call %0 :split %1 %%a if NOT "%_remain%"=="" goto :loop set %1=%_splitRev% set %1_comma=%_splitRev_comma% REM Clear temp vars FOR %%v in (_remain _idx _loop _splitRev _splitRev_comma) do set %%v= goto :eof :split if %_loop%%==2 goto :split_2 set _loop=2 set _remain= set splitRev=%3%_splitRev% set splitRev_comma=%3,%_splitRev_comma% goto :eof :split_2 set _remain=%3 goto :eof :eof
Solution de contournement:
abcdef g hijklmno
Pas d'expansion indirecte des variables
Solution de contournement:
for %%a in (`abcdef/ghijklmno`) do echo %%a
@aschipfl Merci, mais cela semble être la seule gestion des chaînes
dans MsDos6.22 et il ne peut pas séparer les délimiteurs d'une chaîne, comme ,;=
. J'ai ajouté d'autres limitations et solutions de contournement possibles
Quelle version de Windows ou de DOS est exécutée?
il y a longtemps, mais si je me souviens bien, il n'y avait pas non plus de
set / p
sous DOS.