2
votes

I have an old MS DOS computer running DOS 7.10 (ver command gives: windows 98 ver 4.10.2222). I have to make a batch script that basically runs a command 10 or whatever times. I tried using the for command but it gave me ILLEGAL Command For So now I have:

@ECHO off
SET COUNT=0

:MyLoop
IF "%COUNT%" == "10" GOTO EndLoop
ECHO %COUNT%
SET /a COUNT+=1
:EndLoop 
ECHO done

However, this gives me an infinite loop of 0 as if set command is not working. The command DOES work in CMD in windows 10 though. Can anyone suggest what I am doing wrong? Or a way to implement a for loop in DOS 7 batch file.

4
@JeffZeitlin - DOS doesn't have delayed expansion.SomethingDark
I don't have a Windows 98 machine to test, but I'm fairly certain that it's the line set /a count+=1 that's the problem. Try expanding it to set /a count=%count%+1SomethingDark
Rereading the question, I'm not even sure that Win98 command line supported SET /A; variables prior to Windows XP - maybe even in XP - were always strings, not numeric. I recall back in those days that in order to loop five times, I ended up having to do FOR %I IN (1 2 3 4 5) ...Jeff Zeitlin
Yes, @JeffZeitlin, in DOS, there is no set /A; neither is for /L. So you have to use either for %%I in (1 2 3 ...) do, or, if you want to use a goto loop, set "COUNT=%COUNT%_" and if "%COUNT%"=="___...".aschipfl
It is quite easy to test a batch file on newer Windows using cmd.exe as command interpreter on compatibility with command.com. Start the batch file on newer Windows with setlocal DisableExtensions and cmd.exe interprets the batch file like command.com. cmd /? outputs (most) commands affected by enabled/disabled command extensions. The individual help of each affected command explains which features/options require enabled command extensions. Once a batch file is running on newer Windows with disabled command extensions, it's time for testing it on MS-DOS or Windows 95/98.Mofi

4 Answers

3
votes
for %%a in (1 2 3 4 5 6 7 8 9 10) do echo %%a

should count 1 to 10 for you.

Beyond that, you'd need to be more explicit in your requirements.

3
votes

In MS-DOS, there is no arithmetics option /A for the set command. There is also no /L option for for loop.

So you either have to do it like this:

@echo off
set COUNT=

:LOOP
if "%COUNT%"=="__________" goto QUIT
set COUNT=%COUNT%_
echo %COUNT%
goto LOOP
:QUIT
echo Done

Or like this:

@echo off
for %%I in (1 2 3 4 5 6 7 8 9 10) do echo %%I
echo Done

If you want to do many iterations, you could help yourself like this for the first approach:

@echo off
rem // This performs 1000 iterations:
set COUNT=
set LIMIT=__________
set LIMIT=%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%
set LIMIT=%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%%LIMIT%

:LOOP
if "%COUNT%"=="%LIMIT%" goto QUIT
set COUNT=%COUNT%_
echo %COUNT%
goto LOOP
:QUIT
echo Done

Or like this for the second one:

@echo off
rem // This performs 1000 iterations:
for %%I in (1 2 3 4 5 6 7 8 9 10) do for %%J in (1 2 3 4 5 6 7 8 9 10) do for %%K in (1 2 3 4 5 6 7 8 9 10) do echo %%I, %%J, %%K
echo Done
3
votes

This Batch file do what you requested. As is, this example count up to 123, but it can count up to 999 (1000 times, as you requested). If you need more digits, just add the corresponding sections...

EDIT 03/27/2018: Code modified as suggested in comment

EDIT 03/29/2018: Second attempt

@echo off
if not "%1" == "" goto %1

set myself=%0

set count1=0

:MyLoop
   if "%count3%%count2%%count1%" == "123" goto EndLoop
   echo %count3%%count2%%count1%
   call %myself% :incCount
goto MyLoop
:endLoop
echo Done
goto :EOF


:incCount
call %myself% :incDigit %count1%
set count1=%digit%
if %carry% == 0 goto endIncCount
call %myself% :incDigit %count2%
set count2=%digit%
if %carry% == 0 goto endIncCount
call %myself% :incDigit %count3%
set count3=%digit%
:endIncCount
goto :EOF

:incDigit digit
set carry=0
if not "%2" == "" goto next1
   set digit=1
   goto endIncDigit
:next1
if not %2 == 9 goto next2
   set digit=0
   set carry=1
   goto endIncDigit
:next2
if %2 == 8 set digit=9
if %2 == 7 set digit=8
if %2 == 6 set digit=7
if %2 == 5 set digit=6
if %2 == 4 set digit=5
if %2 == 3 set digit=4
if %2 == 2 set digit=3
if %2 == 1 set digit=2
if %2 == 0 set digit=1
:endIncDigit

:EOF

EDIT: New method added

This simpler approach can manage any number of digits in the counter with no modifications:

@echo off
if not "%1" == "" goto %1

set myself=%0

set count=0

:MyLoop
   call %myself% :incCount 
   echo %printCnt%
if not "%printCnt%" == "123" goto MyLoop
echo Done
goto :EOF


:incCount
set newCnt=
set printCnt=
set carry=1
for %%a in (%count%) do call %myself% :incDigit %%a
set count=%newCnt%
if %carry% == 0 goto :EOF
set count=%count%,1
set printCnt=1%printCnt%
goto :EOF

:incDigit digit
set digit=%2
if %carry% == 0 goto endIncDigit
if not %2 == 9 goto next
   set digit=0
   goto endIncDigit
:next
if %2 == 8 set digit=9
if %2 == 7 set digit=8
if %2 == 6 set digit=7
if %2 == 5 set digit=6
if %2 == 4 set digit=5
if %2 == 3 set digit=4
if %2 == 2 set digit=3
if %2 == 1 set digit=2
if %2 == 0 set digit=1
set carry=0
:endIncDigit
set newCnt=%newCnt%,%digit%
set printCnt=%digit%%printCnt%

:EOF
1
votes

Here is a "general" increment function for MS-Dos/Win98. The digits of the value has to be seperated by commas. The result will be stored in the same variable and in a secondary variable for printing (without the commas).
This solution could be extended to solve any arithmetic calculation.

@echo off
if not "%1" == "" goto %1

set counter=0

:loop
call %0 :inc counter print_cnt
echo counter=%print_cnt%
goto :loop
goto :eof

REM *************************************
:inc
set _self=%0
set _counterVar=%2
set _counterPrintVar=%3
set _rev=
set _result=
set _printResult=
set _carry=1
call %_self% :GetIndirectVar _counter %_counterVar%
call %_self% :reverse %_counter%
set %_counterVar%=%_result%
set %_counterPrintVar%=%_printResult%
goto :eof

REM *************************************
:GetIndirectVar
for %%a in (%3) do echo set %2=%%%%a%% > tmp.bat
call tmp.bat
del tmp.bat
goto :eof

REM *************************************
:reverse
if "%2" == "" goto :_add_start
set _rev=%2,%_rev%
shift
goto :reverse

:_add_start
for %%a in (%_rev%) do call %_self% :add_digit %%a
if "%_carry%" == "0" goto :eof
set _digit=1
goto :_add_digit_end

REM *************************************
:add_digit
set _digit=%2
rem echo d=%2 carry=%_carry%
if "%_carry%" == "0" goto :_add_digit_end
set _carry=0

if "%_digit%" == "9" set _carry=1
if "%_digit%" == "9" set _digit=0
if "%_carry%" == "1" goto :_add_digit_end
if "%_digit%" == "8" set _digit=9
if "%_digit%" == "7" set _digit=8
if "%_digit%" == "6" set _digit=7
if "%_digit%" == "5" set _digit=6
if "%_digit%" == "4" set _digit=5
if "%_digit%" == "3" set _digit=4
if "%_digit%" == "2" set _digit=3
if "%_digit%" == "1" set _digit=2
if "%_digit%" == "0" set _digit=1

:_add_digit_end
set _result=%_digit%,%_result%
set _printResult=%_digit%%_printResult%
goto :eof

:eof

You can also use it as an "external" increment function, you only have to name it "increm.bat"

@echo off
set myCounterA=9,9
call increm.bat :inc myCounterA output
echo The new value is %output%