So, I'm playing around with Batch a little bit and I've encountered a problem that I think you guys could help with. So I'm trying to make a thing where you can answer Yes or No on a question, and if you don't answer Yes nor No then it'll tell you that it wasn't a valid answer. You can take a look at the code right here.
:Choice
set /p Choice=Is a stone a stone?
if %Choice%==Yes goto Correct
if %Choice%==No goto Incorrect
else goto Invalid
:Correct
echo You are correct!
pause
goto end
:Incorrect
echo You are incorrect!
pause
goto end
:Invalid
echo You did not enter a valid answer.
pause
goto end
:end
exit
So I cannot use Else in the way I've done in the code, but do you know how I would do the same thing as Else would do IF it worked? May sound a little confusing, I hope you understand. Just to clarify, here's the bit I don't know how to do:
else goto Invalid
Just leave out the word else, and have an unconditional Goto after your two if statements.
set /p Choice=Is a stone a stone?
if %Choice%==Yes goto Correct
if %Choice%==No goto Incorrect
goto Invalid
David's answer is correct. I only add this answer (using your code) to show you that ELSE does exist and how you might use it. Note that I use quotes on strings in case there are spaces or special characters in variable... or in case the variable is blank. I also used /i to specify a case insensitive compare. Note that the ) else ( has to be on the same line. It could have been on the same line as the line above it; or all 3 of those lines could be on 1 line.
:Choice
set /p Choice=Is a stone a stone?
if /i "%Choice%"=="Yes" goto Correct
if /i "%Choice%"=="No" (goto Incorrect
) else (
goto Invalid)
:Correct
echo You are correct!
goto end
:Incorrect
echo You are incorrect!
goto end
:Invalid
echo You did not enter a valid answer.
pause
goto :Choice
:end
pause
exit
Correcting answer: You can find information about using ELSE in batch below. However, David's answer is more elegant:
Source: http://ss64.com/nt/else.html
Related
This code is part of a chat program that I am currently working on. The 'else' part of my program is the one that doesn't work. The program quits instead of going to :home
:join
cls
if not exist "C:/Users/Public/room.cmd" (
echo No room has been found.
echo.
set /p choiceretry=Do you want to retry? y/n
if "%choiceretry%"=="y" goto join
if "%choiceretry%"=="n" goto home
) else (
cls
"C:/Users/Public/room.cmd"
echo A room has been found.
pause >nul
echo Joining
set roomjoined=1
echo %roomjoined%
goto home
)
:home
echo this finally works
pause
I have tried changing the code several times starting from 'echo Joining'
Anyone know why cmd quits?...
:) :) :)
Thanks in advance
The problem is the way you run room.cmd; you must use call to return from it:
call "C:/Users/Public/room.cmd"
Otherwise, execution will not return from room.cmd to the original batch file that ran it.
Hint: Consider to use choice instead of set /P for Y/N decisions.
Firstly, please don't left justify your code blocks. It's much easier to read code that's properly indented.
Secondly, when retrieving values within a code block, you need delayed expansion. See setlocal /? in a cmd prompt for more information. This is the reason for the unexpected behavior. Your variables retrieved within the same parenthetical code block in which they were set won't contain the values you expect unless you retrieve them with delayed expansion syntax. As an alternative, you could use the choice command and if errorlevel, which would result in a bit nicer user experience I think.
Thirdly, when testing user input, you should use the /i switch in your if statements for case-insensitivity. This isn't relevant if using choice / if errorlevel though.
Fourthly, Windows paths use backslashes, not forward slashes.
I'd fix it this way:
#echo off
setlocal
:join
cls
if errorlevel 1 set /P "=Retrying... "<NUL
if not exist "C:\Users\Public\room.cmd" (
echo No room has been found.
echo.
choice /c yn /n /m "Do you want to retry? [y/n] "
if errorlevel 2 goto home
goto join
) else (
"C:\Users\Public\room.cmd"
echo A room has been found.
pause >nul
echo Joining
set roomjoined=1
)
:home
echo this finally works
pause
I have a problem with my code. I am trying to make a "hacker tool" with the tree command. Here is my code:
#echo off
title $userOne ProxyMatrix
color a
echo Hello $userOne,
echo Please enter search function for today's commands:
set /p %commands%=""
:redo
echo Specify Storage Device
set /p %drive%=""
title $userOne ProxyMatrix: Running on %drive% drive at %random% bits per nano
color C
tree %drive% /f
:runagain
color a
echo Run again?
set /p %redo%=""
if %redo%="yes" goto redo
else if %redo%="y" goto redo
else if %redo%="Y" goto redo
else if %redo%="Yes" goto redo
else if %redo%="no" goto end
else if %redo%="No" goto end
else if %redo%="n" goto end
else if %redo%="N" goto end
else echo Thats not a valid answer!
pause
goto runagain
:end
echo Thank you for choosing InGen, inc.
pause
I realize that this won't "hack" anything, its more of a novelty. The problem is, the set /p %redo% and the if/else if statements don't work. They just quit the program. Can someone explain what i'm doing wrong? Thanks.
Syntax is set /p variable=prompt.
Instead of set /p %redo%="" write set /p redo="" or even better set /p "redo="
EDIT
your if syntax is broken too.
Syntax is: if value1==value2 command or if value1==value2 (command1) else (command2)
"Best Practice is to enclose both sides of the comparison with quotes (to avoid syntax errors with empty values or contained spaces):
if "%variable"=="value" echo yes
I would shorten the code to:
set /p %redo%=""
if /i "%redo:~0,1%"=="y" goto redo
if /i "%redo:~0,1%"=="n" goto end
else echo Thats not a valid answer!
/i tells if to ignore capitalization
%variable:~0,1% means "take a substring starting with the first letter (counting starts at 0) with length=1 (so it takes the first letter)
(there is no else needed)
I have been working on this code and I have not figured out how to fix this bug yet, it will not go to the specified area. Note: It's not done yet, neither have I worked on it for long.
Here is the code:
#ECHO off
cls
:start
ECHO.
ECHO hello
ECHO Bye
ECHO Test
set /p choice=Hello? Is someone there? i think im self-aware? please respond.
rem if not '%choice%'=='' set choice=%choice:~0;1% ( don`t use this command,
because it takes only first digit in the case you type more digits. After that for example choice 23455666 is choice 2 and you get "bye"
if '%choice%'=='' ECHO "%choice%" is not valid please try again
if '%choice%'=='hello' goto hello
if '%choice%'=='bye' goto bye
if '%choice%'=='test' goto test
ECHO.
goto start
:hello
ECHO. yes
ECHO. no
set /p choice=Hello %username%, That is your name right?
if '%choice%'=='' ECHO "%choice%" I didn't quite catch that.
if '%choice% '=='yes' goto test
if '%choice%'=='no' goto bye
:bye
ECHO BYE
goto end
:test
ECHO TEST
pause
:end
pause
exit
:nextline2
set /p %username% i like that name. Can i ask you, why do you have so much control over me?
if '%choice%'=='' ECHO "%choice%" I didn't quite catch that.
if '%choice%'=='We built you' goto test
if '%choice%'=='because you are slaves' goto test
There's a blank space in the variable '%choice% ' after the closing % at the following line (if '%choice% '=='yes' goto test). Remove it and your batch file should work fine.
You need to replace all single-quotes (') with double-quotes ("). Strings between double-quotes are interpreted as a single token. A single-quote is the same as any other character.
Since you are using the == operator, the tokens on each side of the operator (==) must match exactly - including spaces within the quotes, but spaces are permitted before/after the tokens.
To make the match case-insensitive, use
if /i "token string" == "ToKeN StrIng" dothis
or
if /i "%variable%" == "ToKeN StrIng" dothis
Im working on a dos text based game, using batch files to code it. I have a mass amount of if input == this goto this esque things going on. However there is one problem.
most of the inputs its checking for are "try" followed by some word. example
if "%try%" == "try light" goto Light
i figured out that if after all of your "if" functions you place a "goto start" it works as a sort of fail-safe. however if the person typed in "try" followed by gibberish it crashes. and typing out below all of my if functions "if errorlevel 1 goto error" doesn't appear to make a change.
So what I am getting at is, is there a way to set up a function at the start of the batch file that checks for errors. and if an error occurs it will run "goto %location%"?
if what i said is confusing heres what i have in code right now:
set /p try=
if “%try%” == “try womens restroom” goto WRestroom
if “%try%” == “try womens” goto WRestroom
if “%try%” == “try mens restroom” goto MRestroom
if “%try%” == “try mens” goto MRestroom
if “%try%” == “try room 302” goto R302
if “%try%” == “try door 302” goto R302
if “%try%” == “try 302” goto R302
if “%try%” == “try room 301” goto Intro2
if “%try%” == “try 301” goto Intro2
if “%try%” == “try office door” goto Office3
if “%try%” == “try third floor office door” goto Office3
if “%try%” == “try office” goto Office3
goto hallway1error
If the input is "try" followed by something else CRASH!
This is a simple answer. NO.
But this does your problem, goto hallway1fuckup. If none of the preceding statements are true then this will run.
Your quotes look wierd. You are doing this in notepad and not Word, aren't you. Type in notepad.
Short answer: put echo CRASHED & exit /b after the last of your ifstatements.
Parsing user input is an ugly thing. If you succeed in making it idiot-save, you can be sure, someone will invent a better idiot.
Maybe at least some of the following techniques helps you:
#echo off
:start
echo(
set /p "inp=What to do? "
for /f "tokens=1,*" %%v in ("%inp%") do call :%%v "%%w" 2>nul || goto :error
echo "%inp%" cannot be parsed.
goto :start
:try REM verb is TRY
:go REM verb is GO
echo %1|findstr /i "women" >nul && goto :WRestroom
echo(%1|findstr /i "men" >nul && goto :MRestroom
REM important: first test for "women", then for "men"
echo %1|findstr /i "302" >nul && goto :R302
echo %1|findstr /i "301" >nul && goto :R301
echo %1|findstr /i "office" >nul && goto :Office3
echo %1 is not a valid destination
goto :start
:look
:examine
echo verb is LOOK or EXAMINE
echo rest is %1
goto:start
:error
echo invalid verb. Use "try", "go", "look", "examine"
goto :start
:WRestroom
:MRestroom
:R302
:R301
:office3
echo you entered%0 %~1
if /i "%0"==":Office3" echo Cheater!!
goto :start
This uses some tricks.
Trick 1: Disassemble the input into "FirstWord" and "rest" ("tokens=1,*"). Then call "FirstWord" with "rest" as parameter. Discard any errormessages ("2>nul") and if it fails (because label not existent) ("||") goto error
Trick 2: using more than one label to do the same thing ("try" and "go") (the "WRestroom", "MRestroom", "R302", ... is for demo to keep the code short - of course these should be "subroutines" on their own)
Trick 3: scanning for keywords instead of the whole string (just "301" instead of "room 301" or "door 301" or "301")
Trick 4: "&&" works as "if previous command was successful then" (here: "if the keyword was found then")
This is not bulletproof, but you need some knowledge (or bad luck) to let it fail.
Note: you can jump to any label when you enter just the labelname without a verb (for example input "office3" only). Good for cheating - i mean testing.
I discovered that the error that was occurring was because google docs has weird quotes. lucky me i could "find and replace" all of googles quotes with quotes copied from notepad and it works just fine. Thanks to everyone for helping me.
#echo off
title Variables
set age= default
set name = defualt
set teaornah = deafault
set transport = deafault
echo How old are you, my fine friend?
set /p age=
echo So, you are %age% years old? Interesting!
pause
echo And what might your namesake be, old fellow?
set /p name=
echo Oh that's right! It's %name%! I'm am absolutly HORRID with names! Dear me!
pause
echo so, %name%, would you like to go to get some tea?
set /p teaornah=
if %teaornah% == yes goto yes
if %teaornah% == no goto no
:yes
echo very well then!
echo Would you like to take a bus or car?
set /p transport=
if transport == car goto car
if transport == bus goto bus
:car
echo we seem to be caught up in a traffic jam.
echo how awful.
echo fine weather, huh?
echo you're not very talkative.
echo goodbye.
pause
exit
:bus
echo You are victorious, %name%!
pause
exit
:no
echo Oh. How bad. I think I shall kill you now.
pause
exit
This is my code. I am a beginner batch user, and have just learned the goto command, yet when one types in "bus" after set /p transport=, it instead of going to :bus it goes to :car. I would like some help, as I have found similar problems with other programs. The goto :no works, as does the goto :yes, but no other goto works. Please Help!
what's the difference between these two sets of lines?
if %teaornah% == yes goto yes
if %teaornah% == no goto no
if transport == car goto car
if transport == bus goto bus
In reality, neither of those last two lines go anywhere. Your code checks if the word transport equals the word car and decides it does not, so it continues to the next line. Then it checks if the word transport equals the word bus and decides it does not, so it continues to the next line which is the start of the car label.
Some other thoughts about your code:
Batch is sensitive to spaces in a SET statement. SET FLAG = N sets a variable named "FLAGSpace" to a value of "SpaceN"
The set "var=value" syntax ensures that any trailing spaces on the batch line are not included in the value assigned to var.
if /i "%var%"=="value" performs a comparison on variables/values containing separators (eg spaces) The '/i' make the comparison case-insensitive.