Batch script loop - windows

I need to execute a command 100-200 times, and so far my research indicates that I would either have to copy/paste 100 copies of this command, OR use a for loop, but the for loop expects a list of items, hence I would need 200 files to operate on, or a list of 200 items, defeating the point.
I would rather not have to write a C program and go through the length of documenting why I had to write another program to execute my program for test purposes. Modification of my program itself is also not an option.
So, given a command, a, how would I execute it N times via a batch script?
Note: I don't want an infinite loop
For example, here is what it would look like in Javascript:
var i;
for (i = 0; i < 100; i++) {
console.log( i );
}
What would it look like in a batch script running on Windows?

for /l is your friend:
for /l %x in (1, 1, 100) do echo %x
Starts at 1, steps by one, and finishes at 100.
WARNING: Use %% instead of %, if it's in a batch file, like:
for /l %%x in (1, 1, 100) do echo %%x
(which is one of the things I really really hate about windows scripting.)
If you have multiple commands for each iteration of the loop, do this:
for /l %x in (1, 1, 100) do (
echo %x
copy %x.txt z:\whatever\etc
)
or in a batch file
for /l %%x in (1, 1, 100) do (
echo %%x
copy %%x.txt z:\whatever\etc
)
Key:
/l denotes that the for command will operate in a numerical fashion, rather than operating on a set of files
%x is the loops variable
(starting value, increment of value, end condition[inclusive] )

And to iterate on the files of a directory:
#echo off
setlocal enableDelayedExpansion
set MYDIR=C:\something
for /F %%x in ('dir /B/D %MYDIR%') do (
set FILENAME=%MYDIR%\%%x\log\IL_ERROR.log
echo =========================== Search in !FILENAME! ===========================
c:\utils\grep motiv !FILENAME!
)
You must use "enableDelayedExpansion" and !FILENAME! instead of $FILENAME$. In the second case, DOS will interpret the variable only once (before it enters the loop) and not each time the program loops.

Template for a simple but counted loop:
set loopcount=[Number of times]
:loop
[Commands you want to repeat]
set /a loopcount=loopcount-1
if %loopcount%==0 goto exitloop
goto loop
:exitloop
Example: Say "Hello World!" 5 times:
#echo off
set loopcount=5
:loop
echo Hello World!
set /a loopcount=loopcount-1
if %loopcount%==0 goto exitloop
goto loop
:exitloop
pause
This example will output:
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Press any key to continue . . .

You could also try this instead of a for loop:
set count=0
:loop
set /a count=%count%+1
(Commands here)
if %count% neq 100 goto loop
(Commands after loop)
It's quite small and it's what I use all the time.

You could do something to the following effect avoiding the FOR loop.
set counter=0
:loop
echo "input commands here"
SET /A counter=%counter%+1
if %counter% GTR 200
(GOTO exit) else (GOTO loop)
:exit
exit

Or you can decrement/increment a variable by the number of times you want to loop:
SETLOCAL ENABLEDELAYEDEXPANSION
SET counter=200
:Beginning
IF %counter% NEQ 0 (
echo %x
copy %x.txt z:\whatever\etc
SET /A counter=%counter%-1
GOTO Beginning
) ELSE (
ENDLOCAL
SET counter=
GOTO:eof
Obviously, using FOR /L is the highway and this is the backstreet that takes longer, but it gets to the same destination.

Very basic way to implement looping in cmd programming using labels
#echo off
SET /A "index=1"
SET /A "count=5"
:while
if %index% leq %count% (
echo The value of index is %index%
SET /A "index=index + 1"
goto :while
)

You can do this without a for statement ^.^:
#echo off
:SPINNER
SET COUNTP1=1
:1
CLS
:: YOUR COMMAND GOES HERE
IF !COUNTP1! EQU 200 goto 2
SET COUNTP1=1
) ELSE (
SET /A COUNTP1+=1
)
goto 1
:2
:: COMMAND HAS FINISHED RUNNING 200 TIMES
It has basic understanding. Just give it a test. :P

DOS doesn't offer very elegant mechanisms for this, but I think you can still code a loop for 100 or 200 iterations with reasonable effort. While there's not a numeric for loop, you can use a character string as a "loop variable."
Code the loop using GOTO, and for each iteration use SET X=%X%# to add yet another # sign to an environment variable X; and to exit the loop, compare the value of X with a string of 100 (or 200) # signs.
I never said this was elegant, but it should work!

I use this. It is just about the same thing as the others, but it is just another way to write it.
#ECHO off
set count=0
:Loop
if %count%==[how many times to loop] goto end
::[Commands to execute here]
set count=%count%+1
goto Loop
:end

The answer really depends on how familiar you are with batch, if you are not so experienced, I would recommend incrementing a loop variable:
#echo off
set /a loop=1
:repeat
echo Hello World!
set /a loop=%loop%+1
if %loop%==<no. of times to repeat> (
goto escapedfromrepeat
)
goto repeat
:escapedfromrepeat
echo You have come out of the loop
pause
But if you are more experienced with batch, I would recommend the more practical for /l %loop in (1, 1, 10) do echo %loop is the better choice.
(start at 1, go up in 1's, end at 10)
for /l %[your choice] (start, step, end) do [command of your choice]

a completely flawless loop
set num=0
:loop
:: insert code
set /a num=%num%+1
if %num% neq 10 goto loop
::insert after code code
you can edit it by changing the 10 in line 5 to any number to represent how many time you want it to loop.

Not sure if an answer like this has already been submitted yet, but you could try something like this:
#echo off
:start
set /a var+=1
if %var% EQU 100 goto end
:: Code you want to run goes here
goto start
:end
echo var has reached %var%.
pause
exit
The variable %var% will increase by one until it reaches 100 where the program then outputs that it has finished executing. Again, not sure if this has been submitted or something like it, but I think it may be the most compact.

Use FOR /l and make sure to use %% instead of %
It will save you headaches.
And try to Set the loop.

(EDITED) I made it so it stops after 100 times
#echo off
goto actual
set /a loopcount=0
:actual
set /a loopcount=%loopcount% + 1
echo %random% %random% %random% %random%
timeout 1 /nobreak>nul
if %loopcount%== 100 goto stop
goto actual
:stop
exit
This will generate 4 random numbers ever 1 second 100 times.
Take out the "timeout 1 /nobreak>nul" to make it go super fast.

I have 2 answers
Methods 1:
Insert Javascript into Batch
#if (#a==#b) #end /*
:: batch portion
#ECHO OFF
cscript /e:jscript "%~f0"
:: JScript portion */
Input Javascript here
( I don't know much about JavaScript )
Method 2:
Loop in Batch
#echo off
set loopcount=5
:loop
echo Hello World!
set /a loopcount=loopcount-1
if %loopcount%==0 goto exitloop
goto loop
:exitloop
pause
(Thanks FluorescentGreen5)

Related

How can I "break" out of a For loop?

Below, when I execute the goto command, it just hangs and I have to Control-C. I tried EXIT /b too. I'm trying to avoid goto's as much as possible. Is there a way to do what I want?
:SUB_bigRandLooper
set /a lcv=0
FOR /L %%s IN ( 0 , 0 , 1 ) DO (
set big-rand=!random:~-4!
echo big-rand is !big-rand!
set /a lcv=%lcv+1
if !big-rand! GTR 9900 goto bigRandLooperWrapup
)
:bigRandLooperWrapup
echo biggest-rand is %big-rand%
echo lcv is %lcv%
EXIT /B
.
The short answer is: No, you can't.
Since you are using for /L and establish an infinite loop and the fact that the loop is preprocessed and cached before it is executed, it cannot be interrupted by goto; goto breaks the loop context, or more correctly spoken, the (/) block context, so no more commands in the block are executed, but the loop itself is still running.
You can prove this by the following code:
for /L %%I in (1,1,100000) do (
echo %%I
if %%I equ 10 goto :SKIP
)
:SKIP
echo skipped
You will see that echo %%I is only executed for %%I from 1 to 10, but execution does not immediately continue at echo skipped but there is a notable delay, because the loop finishes iterating in the background, although no more commands are executed.
There is a work-around though: you could establish an endless loop with goto, like this:
:SUB_bigRandLooper
set /A lcv=0
:bigRangLooperLoop
set big-rand=!random:~-4!
echo big-rand is !big-rand!
set /A lcv+=1
if !big-rand! gtr 9900 goto :bigRandLooperWrapup
goto :bigRangLooperLoop
:bigRandLooperWrapup
echo biggest-rand is %big-rand%
echo lcv is %lcv%
exit /B
I know the goto loop is slower than the for /L loop, but that is the only way to create a breakable infinite loop.
A faster approach is to nest both loop methods: use for /L to iterate a few thousands times and wrap an infinite goto loop around.
An alternative work-around is to make use of the fact that the exit command can break (infinite) for /L loops. But since this also exits the cmd instance the batch file is running in, the loop needs to be placed into a separate cmd instance. Of course the environment is completely separated from the current one. A solution might look like this:
:SUB_bigRandLooper
#echo off
rem // Check for argument, interpret it as jump label if given:
if not "%~1"=="" goto %~1
rem /* Establish explicit `cmd` instance for executing the `for /L` loop;
rem the `for /F` loop implicitly creates the new `cmd` instance for the command
rem it executes, so we do not have to explicitly call `cmd /C` here; the resulting
rem values are echoed by the sub-routine and captured here by `for /F`: */
for /F "tokens=1,2" %%I in ('"%~f0" :bigRandLooperLoop') do (
rem // Assign captured values to environment variables:
set "big-rand=%%I" & set "lcv=%%J"
)
:bigRandLooperWrapup
echo biggest-rand is %big-rand%
echo lcv is %lcv%
exit /B
:bigRandLooperLoop
setlocal EnableDelayedExpansion
set /A lcv=0
for /L %%s in (0,0,1) do (
set big-rand=!random:~-4!
rem /* Explicitly redirect this output to the console window to prevent it from
rem being captured by `for /F` in the main routine too: */
> con echo big-rand is !big-rand!
set /A lcv+=1
if !big-rand! gtr 9900 (
rem // Output found values in order to be able to capture them by `for /F`:
echo !big-rand! !lcv!
rem // Break loop and leave current `cmd` instance:
exit
)
)
endlocal

Confusion on "for /l in %%i ..." always renders "0"

I'm a little confused on why in this code, %rem% always comes back as 0 (even when tested with prime numbers). Can someone please help me? Thanks :D
:PRIME
cls
echo What number would you like to check?
set /p num=
set num2=%num%-1
for /l %%i in (2 1 %num2%) do (
set /a rem=%num% %% %%i
)
if %rem% equ 0 goto NOT_PRIME
goto YES_PRIME
:YES_PRIME
echo %num% is a prime number.
goto AGAIN_PRIME
:NOT_PRIME
echo %num% is not a prime number.
goto AGAIN_PRIME
:AGAIN_PRIME
echo Would you like to check another number? (y/n)
set /p ans=
if '%ans%'=='y' goto PRIME
if '%ans%'=='n' goto START
This is only a portion of the code. The problem is that every number that I test, I get "%num% is not a prime number."
There are two problems in this section:
set num2=%num%-1
for /l %%i in (2 1 %num2%) do (
set /a rem=%num% %% %%i
)
if %rem% equ 0 goto NOT_PRIME
First, you need to use set /a to do calculations on a variable, so it should be:
set /a num2=%num%-1
Second, your for loop runs through all your calculations correctly, but your if line ends up checking only the results of the very last calculation. You need to enable delayed expansion and then include the if statement inside the for loop, like this:
for /l %%i in (2 1 %num2%) do (
set /a rem=%num% %% %%i
if !rem! equ 0 goto NOT_PRIME
)

Windows batch file, division of two numbers with error trapping for division of 0

I am attempting to write a windows batch file which implements division of two with some error trapping if the second number is 0. If the user enters 55 for either number it is supposed to go to a loop which finds the total amount of all results of calculating each number from 1-100 mod 5, + 3
After the loop ends, its supposed to display average of all results and append them to a txt file.
When I attempt, the division, the screen pops up and goes away. Never reaches the loop if i enter 55. Any help is appreciated, thanks!
:FORLOOP
cls
PAUSE
SET COUNTER=0
SET MODNUM=5
SET ADDNUM=3
SET RESULT=0
SET TOTAL=0
SET AVG=0
GOTO LOOP
:LOOP
SET /A COUNTER=COUNTER+1
SET /A "RESULT=((%LOOP% %% %MODNUM%) + %ADDNUM%)"
ECHO %COUNTER% MOD %MODNUM% PLUS %ADDNUM% IS %RESULT%
SET /A "TOTAL=%TOTAL% + %RESULT%"
IF %COUNTER%==100
GOTO AVG
:AVG
ECHO.
SET /A "AVERAGE=(%TOTAL% / 100)"
ECHO AVERAGE OF RESULTS IS %AVG%
ECHO.
#ECHO AVERAGE OF RESULTS IS %AVG% >> results.txt
GOTO EXITLOOP
:EXITLOOP
PAUSE EXIT /B
Without trying it myself, it looks like once you get to :AVG from :LOOP, it then falls into :EXITLOOP, which exits the batch.
I would put your logic check for zero ABOVE your logical check for 55. Division by zero is more dangerous than your 55 check. Ensure the data is valid FIRST before doing anything with it.
There also seems to be no way back from :AVG. It just exits the batch file thereafter.
You're not setting %loop% before using it.
C:\Users\me>SET /A "RESULT=(( % 5) + 3)"
Missing operand.
This means that 3 lines later you get a syntax error:
IF %LOOP%==100
which bombs out because
IF ==100
is invalid syntax.
Did you mean to use %COUNTER% instead of %LOOP%?
When debugging, remove your 'cls' commands so you can see your errors.
You can also run your script from a cmd.exe window and then the output won't just disappear when the script ends.
If you replace your two instances of %LOOP% with %COUNTER%, and then fix another syntax error where there's a newline between
IF %COUNTER%==100
and
GOTO AVG
then at least it finishes without errors. I'll let you determine whether it's working correctly.
You're doing a few things wrong.
First, you're setting a variable called AVERAGE instead of AVG, so the AVG is always going to be 0. Second, you misspelled DIVISION, in your IF NOT %SECONDNUM%==55 GOTO DIVISON
Also, as LinuxDisciple mentions in his answer, batch-files are interpreted on a line by line basis, so you can't have your if and goto on two different lines.
Finally, you have some of the logic of the loop wrong. I think you're trying to do this:
#echo off
#ECHO Carlos Deleon >> results.txt
#ECHO %date% %time% >> results.txt
:MAIN
cls
:FIRSTNUM
ECHO.
ECHO ENTER FIRST NUMBER
SET /P FIRSTNUM=Enter a number and press ENTER :
IF %FIRSTNUM%==55 GOTO FORLOOP
GOTO SECONDNUM
:SECONDNUM
ECHO.
ECHO ENTER SECOND NUMBER
SET /P SECONDNUM=Type a different number and press enter :
IF %SECONDNUM%==55 GOTO FORLOOP
IF %SECONDNUM%==0 GOTO ASKAGAIN
IF NOT %SECONDNUM%==55 GOTO DIVISION
IF NOT %SECONDNUM%==0 GOTO DIVISION
:ASKAGAIN
ECHO.
ECHO INVALID ENTRY, CANNOT DIVIDE BY ZERO, ENTER TWO NEW NUMBERS
GOTO FIRSTNUM
:DIVISION
ECHO.
SET /A RESULT=%FIRSTNUM% / %SECONDNUM%
ECHO %FIRSTNUM% divided by %SECONDNUM% is %RESULT%
#ECHO %FIRSTNUM% divided by %SECONDNUM% is %RESULT% >> results.txt
GOTO FIRSTNUM
:FORLOOP
cls
PAUSE
SET COUNTER=0
SET MODNUM=5
SET ADDNUM=3
SET RESULT=0
SET TOTAL=0
SET AVG=0
GOTO LOOP
:LOOP
SET /A COUNTER=COUNTER+1
SET /A "RESULT=((%COUNTER% %% %MODNUM%) + %ADDNUM%)"
ECHO %COUNTER% MOD %MODNUM% PLUS %ADDNUM% IS %RESULT%
SET /A "TOTAL=%TOTAL% + %RESULT%"
IF %COUNTER% lss 100 GOTO LOOP
:AVG
ECHO.
ECHO %TOTAL%
SET /A "AVG=(%TOTAL% / 100)"
ECHO AVERAGE OF RESULTS IS %AVG%
ECHO.
#ECHO AVERAGE OF RESULTS IS %AVG% >> results.txt
GOTO EXITLOOP
:EXITLOOP
PAUSE EXIT /B
Note that if lss means that it keeps looping while the COUNTER is less than 100, which is what you're trying, instead of only loops if the COUNTER is already 100

goto was not expected at this time batch

#echo off
:start
set string=
set lo=1
set a=0
set b=0
set cl=1
set cloop=
set google=0
set k=0
set r=0
set id=
set t=0
set f=0
set /p string=?
if defined string (
echo %string%
goto loop
) else (
echo please enter a string
goto start
)
:loop
set a=
for /f "tokens=%lo%" %%G IN ("%string%") DO echo %%G
if defined a (
echo %a%
set google=0
set /p cloop=<greetings.txt
pause
:cloop
set b=
for /f "tokens=%cl%" %%g IN ("%cloop%") DO set b=%%g
if defined string (
if %a%==%b% goto greetings
set /a cl=%cl%+1
goto cloop
) else (
set cl=0
set /a lo=%lo%+1
goto loop
)
) else (
goto google
)
:greetings
set f=0
set k=0
set r=0
set /p id=<greetingtone.dat
for /f "tokens=%cl%" %%g IN ("%id%") DO set t=%%g
start greeting.bat
call greeting.bat
goto talk
:google
echo not done yet
pause
goto start
i have narrowed it down to this line
if %a%==%b% goto greetings
when i remove it it runs
i have looked but i have no idea why it does not work
please help the greetings.txt has "hi hello grunt"
i think it might be the variables
If %a% or %b% are empty values, it is likely the compare is incomplete, and it is saying that the goto is not expected yet. For instance, if you type the following at a C:\ prompt:
c:\>if a== echo ok
c:\>if ==a echo ok
echo was unexpected at this time.
c:\>if == echo ok
ok was unexpected at this time.
c:\>
If you enclose each value in quotes, then the comparison will still work even if one or both of the values are empty. For instance:
if "%a%"=="%b%" goto greetings
The normal reason for that an unexpected word in an IF statement is that IF has a very specific syntax, IF item1 operator item2 actionstatement(s).
What is likely to be happening is that item1 AND item2 appear to be missing, so IF resolves that as IF == goto greetings. Since goto is not one of its known operators (==, equ, neq, leq, lss, geq, gtr`) then it complains.
The question from here is - why do %a% and %b% appear to be empty?
Within a block statement (a parenthesised series of statements), the entire block is parsed and then executed. Any %var% within the block will be replaced by that variable's value at the time the block is parsed - before the block is executed.
Hence, IF (something) else (somethingelse) will be executed using the values of %variables% at the time the IF is encountered. In your case, that means the outermost IF - in if defined string.
Two common ways to overcome this are 1) to use setlocal enabledelayedexpansion and use !var! in place of %var% to access the changed value of var or 2) to call a subroutine to perform further processing using the changed values.
Next problem is using a label within a block. Not a good idea. On some versions, a label will terminate the block. Call a subroutine instead.
call :cloop
...
goto start
:cloop
(whatever needs to be done)
goto :eof
(note that :cloop and :EOF have a required colon. on cloop it means "this is an internal subroutine - it's in the cuurrent batchfile." :EOF is a predefined label understood by CMD to mean end of file.)

Batch File input validation - Make sure user entered an integer

I'm experimenting with a Windows batch file to perform a simple operation which requires the user to enter a non-negative integer. I'm using simple batch-file techniques to get user input:
#ECHO OFF
SET /P UserInput=Please Enter a Number:
The user can enter any text they want here, so I would like to add some routine to make sure what the user entered was a valid number. That is... they entered at least one character, and every character is a number from 0 to 9. I'd like something I can feed the UserInput into. At the end of the routine would be like an if/then that would run different statements based on whether or not it was actually a valid number.
I've experimented with loops and substrings and such, but my knowledge and understanding is still slim... so any help would be appreciated.
I could build an executable, and I know there are nicer ways to do things than batch files, but at least for this task I'm trying to keep it simple by using a batch file.
You're probably not doing this in a DOS batch file. Or at least, support for set /p is unheard of for me in DOS :-)
You could use substrings. In fact I have written a parser for a specific regular language that way once, but it's cumbersome. The easiest way would probably be to assign the contents of %userinput% to another variable, using set /a. If the result comes out as 0 you need to check whether the input itself was 0, otherwise you can conclude it was a non-number:
#echo off
setlocal enableextensions enabledelayedexpansion
set /p UserInput=Enter a number:
set /a Test=UserInput
if !Test! EQU 0 (
if !UserInput! EQU 0 (
echo Number
) else (
echo Not a number
)
) else (
echo Number
)
However, this works only for numbers in the range of Int32. If you just care for any number (possibly floating-point as well) then you need to resort to the loop-based approach of dissecting it.
NOTE: Updated to solve the space issues. However, there is still a problem lurking: Entering 123/5 yields "number", since set /a can evaluate this ...
Thanks all. I was trying to make it harder for myself looking at loops and string manipulation. I used your tips on math evaluation and comparison. Here's what I finally came up with as my concept script:
:Top
#ECHO OFF
ECHO.
ECHO ---------------------------------------
SET /P UserInput=Please Enter a Number:
ECHO.
ECHO UserInput = %UserInput%
ECHO.
SET /A Evaluated=UserInput
ECHO Math-Evaluated UserInput = %Evaluated%
if %Evaluated% EQU %UserInput% (
ECHO Integer
IF %UserInput% GTR 0 ( ECHO Positive )
IF %UserInput% LSS 0 ( ECHO Negative )
IF %UserInput% EQU 0 ( ECHO Zero )
REM - Other Comparison operators for numbers
REM - LEQ - Less Than or Equal To
REM - GEQ - Greater Than or Equal To
REM - NEQ - Not Equal To
) ELSE (
REM - Non-numbers and decimal numbers get kicked out here
ECHO Non-Integer
)
GOTO Top
This method catches all numbers and can detect whether it's positive, negative, or zero. Any decimal or string will be detected as non-integers. The only edge case I've found is a string with spaces. For example, the text "Number 1" will cause the script to crash/close when the user input is evaluated as math. But in my situation, this is fine. I don't want my script to go on with invalid input.
You can also use a quite simple trick:
echo %userinput%|findstr /r /c:"^[0-9][0-9]*$" >nul
if errorlevel 1 (echo not a number) else (echo number)
This uses findstr's regular expression matching capabilities. They aren't very impressive but useful at times.
This is the same idea as that of Johannes..
SET /A sets a numeric value. If the input is not a number, it changes it to 0.
That's what you can exploit here to do your check.
#ECHO OFF
SET /P UserInput=Please Enter a Number:
IF %UserInput% EQU 0 GOTO E_INVALIDINPUT
SET /A UserInputVal="%UserInput%"*1
IF %UserInputVal% GTR 0 ECHO UserInput "%UserInputVal%" is a number
IF %UserInputVal% EQU 0 ECHO UserInput "%UserInputVal%" is not a number
GOTO EOF
:E_INVALIDINPUT
ECHO Invalid user input
:EOF
As an alternative, you could always create a little javascript file and call it from your batchfile. With parseInt() you could force the input to be an integer, or you could roll your own function to test the input.
Writing the javascript is just as fast as the batchfile, but it's much more powerful. No IDE or compiler required; notepad will do. Runs on every windows box, just like your batchfiles. So why not make use of it?
You can even mix batchfiles and javascript. Example:
contents of sleep.js:
var SleepSecs=WScript.Arguments.Item(0);
WScript.Sleep(SleepSecs*1000)
contents of sleep.cmd:
cscript /nologo sleep.js %1
You can now call this from a batchfile to make your script sleep for 10 seconds. Something like that is difficult to do with just a plain batchfile.
sleep 10
As pointed out by ghostdog74, the answers posted by Joey Mar 26 '09 (score 10) and Wouter van Nifterick Mar 26 '09 (score 5) don't work.
The answer posted by Joey Mar 25 '10 (score 2) does work, except that redirection symbols and '&' cause syntax errors.
I think the best and simplest solution is the one posted by Sager Oct 8 '14 (score 0). Unfortunately, it has a typo: ‘"%a"’ should be ‘"%a%"’.
Here's a batch file based on Sager's answer. Redirection symbols and '&' in the input don't cause problems. The only problems I could find were caused by strings containing double quotes.
#echo off & setlocal enableextensions & echo.
set /p input=Enter a string:
SET "x=" & for /f "delims=0123456789" %%i in ("%input%") do set x=%%i
if defined x (echo Non-numeral: "%x:~0,1%") else (echo No non-numerals)
In addition to the remark about the error that occures when spaces are part of the users input. You can use errorlevel errorlevel=9165. It can be used for the spaces in a string or for the error handling of 'no' input.
Kind Regards,
Egbert
You might also like this one - it's short and easy. This one use the multiplication trick to set TestVal. Comparing TestVal against UserInput allows all numeric values to get through including zeroes, only non-numerics will trigger the else statement. You could aslo set ErrorLevel or other variables to indicate a failed entry
#ECHO OFF
SET TestVal=0
SET /P UserInput=Please Enter a Number:
SET /A TestVal="%UserInput%"*1
If %TestVal%==%UserInput% (
ECHO You entered the number %TestVal%
) else ECHO UserInput "%UserInput%" is not a number
GOTO EOF
:EOF
I know this is years old, but just to share my solution.
set /p inp=Int Only :
:: Check for multiple zeros eg : 00000 ::
set ch2=%inp%-0
if %inp% EQU 0 goto :pass
if [%inp%]==[] echo Missing value && goto :eof
if %inp:~0,1%==- echo No negative integers! && goto :eof
set /a chk=%inp%-10>nul
if %chk%==-10 echo Integers only! && goto :eof
:pass
echo You shall pass
:eof
Tested and working on Windows 8.
you can reinvent the wheel and grow a few white hairs doing string validation in batch, or you can use vbscript
strInput = WScript.Arguments.Item(0)
If IsNumeric(strInput) Then
WScript.Echo "1"
Else
WScript.Echo "0"
End If
save it as checkdigit.vbs and in your batch
#echo off
for /F %%A in ('cscript //nologo checkdigit.vbs 100') do (
echo %%A
rem use if to check whether its 1 or 0 and carry on from here
)
You can validate any variable if its number:
SET "var="&for /f "delims=0123456789" %i in ("%a") do set var=%i
if defined var (echo."NIC">nul) else (echo."number")
If you want some sort of a loop and default set up for that particular question, then here's my method for doing this.
Notes on the code within.
#echo off
setlocal EnableDelayedExpansion
set "ans1_Def=2"
:Q1
set /p "ans1=Opt 1 of 1 [Value 1-5 / Default !ans1_Def!]: "
:: If not defined section. This will use the default once the ENTER key has been
:: pressed and then go to :Q2.
if not defined ans1 (
echo/ & echo ENTER hit and the default used. Default is still: !ans1_Def! & echo/
set "ans1=!ans1_Def!" && goto :Q2 )
:: This section will check the validity of the answer. The "^[1-5]$" will work
:: for only numbers between one and five in this example but this can be changed
:: to pretty much suit the majority of cases. This section will also undefine
:: the ans1 variable again so that hitting the ENTER key at the question
:: will work.
echo %ans1%|findstr /r /c:"^[1-5]$" >nul
if errorlevel 1 (
echo/ & echo At errorlevel 1. Wrong format used. Default is still: !ans1_Def! & echo/
set "ans1=" && goto Q1
) else ( echo Correct format has been used. %ans1% is the one. && goto :Q2 )
:Q2
echo/
echo -----------------------------
echo/
echo Now at the next question
echo !ans1!
echo/
pause
exit
Try this:
set /p numeric=enter a number
(
(if errorlevel %numeric% break ) 2>nul
)&&(
echo %numeric% is numeric
)||(
echo %numeric% is NOT numeric
)
Just try this
#echo off
SET constNum=100
:LOOP
Set /p input=Please input a number less than %constNum% :
if "%input%" == "" echo Blank is not allowed & goto LOOP
SET "notNumChar="
for /f "delims=0123456789" %%i in ("%input%") do set notNumChar=%%i
if defined notNumChar (
echo %input% is a string
goto LOOP
) else (
REM Remove leading 0 if it has. eg: 08→8
FOR /F "tokens=* delims=0" %%A IN ("%input%") DO SET inputNum=%%A
)
REM Compare
if defined inputNum (
echo %inputNum%
if %inputNum% equ %constNum% & goto LOOP
if %inputNum% gtr %constNum% & goto LOOP
if %inputNum% lss %constNum% & goto CONTINUE
)
:CONTINUE
:: Your code here
:ASK
SET /P number= Choose a number [1 or 2]:
IF %number% EQU 1 GOTO ONE
IF %number% NEQ 1 (
IF %number% EQU 2 GOTO TWO
IF %number% NEQ 2 (
CLS
ECHO You need to choose a NUMBER: 1 OR 2.
ECHO.
GOTO ASK
)
)
It works fine to me. If he chooses numbers less or greater, strings, floating number etc, he wil receive a message ("You need to choose a NUMBER: 1 OR 2.") and the INPUT will be asked again.
#echo off
setlocal enableextensions enabledelayedexpansion
set /p UserInput=Enter a number:
set /a Test=UserInput
if !Test! EQU 0 (
if !UserInput! EQU 0 (
echo Number
) else (
echo Not a number
)
) else (
echo Number
)
yeaph everthing is great
but you forget about one little thing
0 also is a digit
;(
This is more of a user friendly way.
if %userinput%==0 (
cls
goto (put place here)
)
if %userinput%==1 (
cls
goto (put place here)
)
if %userinput%==2 (
cls
goto (put place here)
)
if %userinput%==3 (
cls
goto (put place here)
)
if %userinput%==4 (
cls
goto (put place here)
)
if %userinput%==5 (
cls
goto (put place here)
)if %userinput%==6 (
cls
goto (put place here)
)if %userinput%==7 (
cls
goto (put place here)
)
if %userinput%==8 (
cls
goto (put place here)
)
if %userinput%==9 (
cls
goto (put place here)
)
This can be used for any type of user input.
for me this is working for all non-zero values ..should i be cautious of some rare cases?
set /a var = %1
if %var% neq 0 echo "it is number"
pause

Resources