Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I was trying to create a simple program that would show up your name after you entered it.
After spending a few hours trying to get this batch file to work on a windows 10 and windows 7 computers, I can't still figure out what is the problem. After you input your answer whether or not you confirm that that is your name, it is still not working.
I've tried to debug by putting pause just about everywhere and it continues not to work.
Can somebody please point out what is wrong? Thanks.
Here is my code:
ECHO OFF
setlocal
COLOR A
cls
:getName
ECHO test
echo Please input name.
set "name="
SET /P NAME=
if not defined NAME goto getName
ECHO %NAME%, is this correct? Y/N
set /p 097=
if %O97%==Y goto :begin
set favvid=0
set hack=0
:b
echo Input name
set name=
set /P name=
echo %name%, correct? Y/N
set 897=
set /p 897=
if %897%==N goto :c
if %897%==Y goto :begin
:c
echo Input name
set name=
set /P name=
echo %name%, correct? Y/N
set 897=
set /p 897=
if %897%==N goto b
if %897%==Y goto begin
echo Name = %NAME% Is now your name. Too many attempts
:begin
echo Hello %Name%
pause
Avoid starting variable names with a number, this will avoid the
variable being misinterpreted as a parameter:
%123_myvar% in a batch script is parsed and then executed as %1 23_myvar
For proof, force echo ON.
And use (note that variable first character is not cipher zero but letter O.
set /p "O97=%name%, correct? Y/N "
if "%O97%"=="Y" goto :begin
rem note quoting in above commands
Consider using the CHOICE command as an alternative to SET /P (but accepts only one character/keypress).
Two errors on the if lines:
You should not use numbers to start variables in a batch file as they are interpreted as the arguments passed to the batch file. %0 is the batch file itself. %1 is the first, %8 is the 8th argument etc. (You can try echo --%0--%1--%097%-- in the batch file to see what result it gives you.)
Instead of this if "%097%"=="Y" goto begin
Use this if "%Answer%"=="Y" goto begin
Now also note that while your line set /p 097= has 097 when you
test for it in the next line with %O97% you do not have a 0 but
you have the letter O. This makes your test fail every time.
You need to put the string in quotes, like so:
if "%Answer%"=="Y" goto begin
Finally note that the test is case sensitive. So when the user presses y it will be interpreted as the wrong answer. You need to add a /I to your test:
if/I"%Answer%"=="Y" goto begin
One more point. After the goto you put colon some places, some places not, it is facultative but it is neater to keep it consistent.
Related
I'm trying to take some user input defined variables to decide whether or not to enter the loop and execute a copy and rename followed by deletion of the original file as it will no longer be needed.
set /p multiTune="Does your tune file need to be shared with multiple
Element sequences? (y/n) "
Echo Multi Tune is %multiTune%
if "%multiTune%"=="y" (set /p tuneCount="How many sequences will need to share your tune file? ")
Echo Tune count is %tuneCount%
pause
if "%multiTune%"=="y" (SET /p tuneName="Enter the file letter/number combination for the R quant of your tune file. ") else (#ECHO The user specified there is no need for a second tune.)
Echo Tune Name is %tuneName%
pause
if "%multiTune%"=="y" (SET /a tuneCount+=1) else(set /a tuneCount-=tuneCount)
Echo Tune count is now %tuneCount%
pause
:loop
if "%tuneCount%"=="0" goto exitloop
Set /p seqNumber="Enter the number for one of the sequences."
copy %tuneName%.D.pdf "S%seqNumber%-TUN1_%tuneName%.D.pdf"
echo %tuneName%.D.pdf renamed to S%seqNumber%-TUN1_%tuneName%.D.pdf
pause
Set /a tuneCount-=1
if "%tuneCount%"=="1" DEL "%tuneName%.D.pdf"
if "%tuneCount%"==1 goto exitloop
Echo %tuneCount%
pause
goto loop
:exitloop
All of the echos and pauses are just for testing purposes to make sure I have the correct values in my variables.
The batch file runs fine with the variables containing the correct strings and values up until the line:
if "%multiTune%"=="y" (SET /a tuneCount+=1) else(set /a tuneCount-=tuneCount)
The file says something is unexpected and closes at this point so i havent gotten a chance to figure out if the looped portion even works. The point of the +1 is so that it enters the loop and executes the commands until it gets to 1 and skips the loop if it equals 0.
I read a bunch of information about setlocal delayedexpansion and using !'s around variables instead of %'s. I'm not sure how to implement this or if this applies to my problem at all. I know there is probably an easier way to do the if statements but I'm a novice and that was the easiest way for me to understand it as I've been learning on the fly through trial and error, and everything you see is the results of a single day of learning.
Any help would be much appreciated. I tried to be as detailed as possible about what it is I'm trying to do but if you have any questions I will do my best to answer.
I really think you are making the things so MUCH complicated...
Have a corrected piece of the code you provided us (Note: I did not touch the loop subroutine to be on-topic):
#echo off
choice /m "Does your tune file need to be shared with multiple element sequences? (y/n) " /C:yn /N
rem Echo Multi Tune is %errorlevel%
rem If errorlevel equals to 1 user input is "Y", it is 2 it is "N". (I commented the "echo" command as it changes the errorlevel value).
if errorlevel 2 goto question_N
if errorlevel 1 goto question_Y
:question_Y
set /p tuneCount="How many sequences will need to share your tune file? "
set /p tuneName="Enter the file letter/number combination for the R quant of your tune file. "
SET /a "tuneCount+=1"
goto loop
:question_N
set /p tuneCount="How many sequences will need to share your tune file? "
ECHO The user specified there is no need for a second tune.
set /a "tuneCount-=tuneCount"
goto loop
:loop
rem [Code you provided above]
I hope you are fine with this, testing it and it works!
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.
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.
I'm trying to adjust a Windows batch variable within a loop using the set /p command. After the keyboard input the variable still contains the old value. I have read that the variable set via set /p has only local scope. But I do not understand what "local" really means here.
#echo off
setlocal EnableDelayedExpansion
set a=4
echo Inital A: %a%
:LoopLabel
MODE | find %a% >nul 2>&1
IF %ERRORLEVEL% NEQ 0 (
set /p "a=enter new a: "
echo a=%a%
goto LoopLabel
)
The output is:
Inital A: 4
enter new a: 5
a=4
enter new a: 6
a=5
enter new a: 7
a=6
Does anyone have an idea and can me explain why this is happening?
Many Thanks,
Jonny
Executing code inside the IF is the problem. Check this out:
#echo off
set a=4
echo Inital A: %a%
:LoopLabel
MODE | find "%a%" >nul 2>&1
IF %ERRORLEVEL% EQU 0 goto stuff
set /p "a=enter new a: "
echo a=%a%
goto LoopLabel
:stuff
The set /p is executed outside of the IF, so it works fine even without delayed expansion.
All of the commands inside the IF block get evaluated at the same time (in parallel), so when
echo a=%a%
runs, it is unaware of any new value assigned by
set /p "a=enter new a: "
To further clarify, your a does in fact contain the new value, but the echo a=%a% was executed using the old value.
One solution is to use IF and labels to get the expected program flow, while avoiding multi-step execution within an IF block.
Also you're going to get an error from find unless either your entered value is quoted or you add quotes around %a% when you feed it to find.
Alternatively you can use delayed expansion on your a value to get its value "after" set /p has changed it.
To do this, you would change
echo a=%a%
to
echo a=!a!
The only variable scope that I know of in batch is the %1...%9 and %* in called labels. Otherwise everything is global, including your a set by set /p.
Okay so I am currently creating a Artificial Intelligence program (VERY basic),
and I need to be able to log the name inputted by the user. I don't understand from other articals posted.
Here's the area of code:
set /p input= Before we talk, I'd like to ask your name so I can properly address you. Please print your name.
set /p Name=
As you can see here, we have an input area and I need the file to save the inputted text, and re-open the file and use the name, every time you go onto this program.
Thanks in advance for any help!
#echo off
setlocal EnableDelayedExpansion
call :GetName
if not defined Name (
echo Before we talk, I'd like to ask your name. Please print your name.
set /p Name=
echo set "Name=!Name!" >> "%~F0"
) else (
echo Hello %Name%, I am glad to see you again.
)
rem The rest of the code goes here...
goto :EOF
rem Be sure that the next is the last line in this file:
:GetName
set /p Input=Enter name?
echo set Input=%input% > "c:\somefolder\somefile.bat"
to use
if not defined %input% call "c:\somefolder\somefile.bat"
See if /?, echo /?, and set /?.
I have a code that is shared by 6 different bat scripts below that takes an input argument. I wonder if I can externalize this piece in a seperate bat script and import it instead, so everytime I update this piece of code, I don't have to update all 6 bat scripts.
Code:
:Loop
IF "%1"=="" GOTO Prompt
SET VAR=%1
GOTO Continue
SHIFT
GOTO Loop
:Prompt
set /p VAR="Check which value? "
GOTO Continue
:Continue
Yes, using redirection.
Take this solution.bat file
set /p myvar=< somestring.txt
Where somestring.txt contains "abc"
myvar will now exist as an environment variable with abc.
Your code is supposed to set VAR to the first argument. If the first arg is missing then you want to prompt for a value.
First off, I would simplify your logic.
set "VAR=%~1"
if not defined VAR set /p "VAR=Check which value? "
Once simplified like above, I don't see why you would feel a need to externalize the code. But it could be done.
In your main script
call getArg.bat %1
And here is getArg.bat
set "VAR=%~1"
if not defined VAR set /p "VAR=Check which value? "
exit /b