0

I'm making a simple batch script to figure out arrays in batch script.

The code:

@echo off
setlocal EnableDelayedExpansion
set inputCount=0
set outputCount=0

:input
cls
set /p !number%inputCount%!=Input %inputCount%: 
set /a inputCount=%inputCount%+1
if %inputCount% geq 3 goto output
goto input

:output
cls
echo !number%outputCount%!
set /a outputCount=%outputCount%+1
if %outputCount% geq 3 goto exit
goto output

:exit
pause
echo exit

On line 4, I set outputCount to 0, I then don't change outputCount until line 16 where I add 1 to it.

I expected the output of line 16 to be outputCount=0+1=1 therefore making outputCount=1. However, when I run the code with echo on to see exactly what it's doing, the output for line 16 is outputCount=2+1=3 setting outputCount to 3.

It seems that the program is setting outputCount to 2 instead of 0 at some point before line 16 but I can't see why.

Compo
  • 36,585
  • 5
  • 27
  • 39
Finn Perry
  • 67
  • 1
  • 7
  • As you are clearing the screen in each iteration, you only see the last execution of the `:output` loop. Try the code removing the `cls` command – MC ND Oct 07 '17 at 10:55
  • This does not look right. set /p !number%inputCount%! – Squashman Oct 07 '17 at 13:24
  • As above, _unless you've failed to include the code which sets variables as `number0`, `number1` & `number2` prior to the snippet you've posted_. If you don't have those variables set, then perhaps you should remove the exclamation marks from your `set /p` and `echo` statements and delete the then unnecessary `setlocal EnableDelayedExpansion` line. – Compo Oct 07 '17 at 14:25

1 Answers1

0

First, take a look on Debugging a batch file as this is a lesson you need to learn on coding a batch file.

Second, read the answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line? which offers additional information to the help output on running in a command prompt window set /?.

It looks like you want to define the environment variables number0, number1 and number2 with a string assigned to them by user input.

The command to use to prompt a user for a string is either

set /P "variable=prompt text: "

or

set /P variable="prompt text: "

The first variant is in general recommended although most often not used by batch file coding newbies because of not knowing how to use the double quotes right on assigning a string to an environment variable. The second variant is specific for set /P also possible and in some very rare cases really needed, but in my point of view should be avoided to use because of the double quotes are interpreted different on using set without /P.

So let us look on your code with commenting out with rem four lines, appending one more line with set at end of the batch file and run that batch file from within a command prompt window:

rem @echo off
setlocal EnableDelayedExpansion
set inputCount=0
set outputCount=0

:input
rem cls
set /p !number%inputCount%!=Input %inputCount%:
set /a inputCount=%inputCount%+1
if %inputCount% geq 3 goto output
goto input

:output
rem cls
echo !number%outputCount%!
set /a outputCount=%outputCount%+1
if %outputCount% geq 3 goto exit
goto output

:exit
rem pause
echo exit
set number

Output is at end just a line with NUMBER_OF_PROCESSORS=2. There are no environment variables number0, number1, number2 which would be also output by set number. And the command line echo !number%outputCount%! in file results three times in the information that ECHO is OFF.

The reason can be seen on looking on the output command lines really executed after preprocessing each line by Windows command interpreter.

set /p !number%inputCount%!=Input %inputCount%:

The string entered by the user, if not just RETURN or ENTER was hit by the user on prompt, should be assigned to the environment variables of which name are stored in the environment variables number0, number1 and number2. But the environment variables number0, number1 and number2 are never defined by your batch file as your intention is to store the input strings into the variables with name number0, number1 and number2. So this command line is finally on execution:

set /p =Input 0:
set /p =Input 1:
set /p =Input 2:

Those command lines would result in an exit of batch processing because of a syntax error, but this does not occur here because of usage of delayed expansion as it can be seen in the console window.

The solution is a batch code as follows:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "Index=0"

:Input
cls
set /A Index+=1
set /P "Number%Index%=Input %Index%: "
if not %Index% == 3 goto Input

cls
set "Index=0"

:Output
set /A Index+=1
if defined Number%Index% echo Number%Index%=!Number%Index%!
if not %Index% == 3 goto Output

endlocal

The output of this batch file on entering on first prompt Hello!, on second prompt nothing and on third prompt Bye! is:

Number1=Hello!
Number3=Bye!

Okay, we have not entered a number as we have the freedom to type anything from nothing to bad strings like Double quote " or | or < or > are bad inputs on user prompt on being prompted for an input. But the batch file works as expected now.

Further please note that the string after set /A is an arithmetic expression which is parsed completely different to any other string on a command line. For examples the current values of environment variables can be referenced by using just the variable name without surrounding percent signs or exclamation marks. That make it possible to use variables in arithmetic expression within an IF or FOR command block without usage of delayed expansion. The help output on running set /? in a command prompt window explains this different parsing behavior quite good as well as which operators can be used like += in the arithmetic expression.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • cls /?
  • echo /?
  • endlocal /?
  • goto /?
  • if /?
  • rem /?
  • set /?
  • setlocal /?

Some more hints:

Don't use just exit in a batch file, use exit /B or goto :EOF, see Where does GOTO :EOF return to?

After verification that the user entered anything at all and the entered string is really a number (decimal, octal or hexadecimal), make sure to process the number right according to your and the users' expectations. What I mean here is demonstrated with:

@echo off
set "Number=020"
set /A Number+=1
echo Result=%Number%
pause

What do you expect as result, 21 or the real output result 17?

A number string starting with 0 is interpreted as octal number. A number string starting with 0x or 0X is interpreted as hexadecimal number. Change 020 to 008 and the result is 1. Why? 008 is invalid for an octal number and therefore replaced by 0 which is incremented by one.

Mofi
  • 46,139
  • 17
  • 80
  • 143