I have a batch file (tickets.bat) and each time you create a different ticket, by setting multiple variables and echoing the variables to a text file, I want the ticket number to go up by 1. I tried to do this by creating a number.txt file and each time you go through the loop and create a new ticket, it sets %pnumber% to the text file, and then sets %number% to %pnumber% plus 1. But %pnumber% keeps setting to 0, even when the number.txt file contains the number 1 and doesn't change. This is what I have:
:start
cls
echo Enter Ticket Info Here:
set /p name="Name:"
echo Press Enter to Show Ticket Preview
set /a pnumber=C:\Batch\ticket\number.txt
set /a number=%pnumber%+1
echo %number% > "C:\Batch\ticket\number.txt"
echo %name% Ticket Number %number%
pause
goto start
It looks like my problem is that %pnumber% always sets to 0. Unless I'm missing something else. Basically, I need it to always increase %number% by 1, even if you close the Batch job and open it up again, so that's why I went to using a .txt file. Is it not seeing the number in the text file or something? It's one number on one line. Thank you.
Try Like this :
#echo Off
:start
cls
echo Enter Ticket Info Here:
set /p name="Name:"
echo Press Enter to Show Ticket Preview
set /p pnumber=<C:\Batch\ticket\number.txt
set /a number=%pnumber%+1
echo %number% >C:\Batch\ticket\number.txt
echo %name% Ticket Number %number%
pause
goto start
Related
I'm creating a D&D style RPG game using batch files and I saw another person using a login feature that creates a batch file that returns you to where you left off. so I tried to replicate it. Almost everything works except for the fact that it won't create the batch file to allow you to go back. When you go through the process of creating a login it goes through it like normal and on the next screen under start even displays that your username is what you set it as but it won't create the batch file. Some of the code might be scattered because I'm still learning and some of it unfinished but this is what I have so far.
title Lost Mine of Phandelvor
#echo off
:entergame
cls
echo.
echo Welcome to Lost Mine of Phandelvor
echo -------------------
echo.
echo 1. Create Account
echo 2. Login
echo 3. Exit
echo.
set /p input=
if %input% EQU 1 goto createuser
if %input% EQU 2 goto login
if %input% EQU 3 exit
if %input% GEQ 4 goto entergame
:createuser
cls
echo.
echo What would you like your Username to be?
set /p username1=
set v1f=0
goto checkforspaces
:checkforspaces
set x=!v1f!
set Letter%v1f%=!username1:~%x%,1!
if "!Letter%v1f%!" EQU " " (
echo.
echo.
echo Sorry you can't use spaces in your Username.
pause>nul
goto entergame
)
if NOT "!Letter%v1f%!" EQU "" (
set /a v1f=%v1f%+1
)
echo.
echo What would you like your Password to be?
set /p password1=
goto DATA_VALUES
:login
cls
set /p name=Username:
if not exist "%name%.bat" (
echo That is not a valid Username.
pause>nul
goto entergame
)
set /p pass1=Password:
call %name1%.bat
if not %password1% EQU %pass1% (
echo That is not a valid Password.
pause>nul
goto entergame
)
goto create
:DATA_FILES
set lvl1=1
set exp1=0
set expmax1=300
set gp1=10
set hp1=12
set ac1=15
set profbonus1=2
set str1=4
set dex1=1
set con1=2
set int1=0
set wis1=2
set cha1=2
set destination=SAVE_GAME_FILES
set destination2=SAVE_GAME_FILES
goto SAVE_GAME_FILES
:SAVE_GAME_FILES
(
echo set username1=%username1%
echo set password1=%password1%
:DATA_VALUES
echo set lvl1=%lvl1%
echo set exp1=%exp1%
echo set expmax1=%expmax1%
echo set gp1=%gp1%
echo set hp1=%hp1%
echo set ac1=%ac1%
echo set profbonus1=%profbonus1%
echo set str1=%str1%
echo set dex1=%dex1%
echo set con1=%con1%
echo set int1=%int1%
echo set wis1=%wis1%
echo set cha1=%cha1%
echo set destination=%destination%
echo set destination2=%destination2%
)>%username1%.bat
goto start
:start
cls
echo.
echo Currently logged in as %username1%
echo.
echo Welcome to my fantasy style role playing game.
echo You will need to create a character.
echo.
echo Enjoy!
echo.
echo 1. Continue to Character Selection
echo 2. Exit
echo.
set /p input=
if %input% EQU 1 goto create
if %input% EQU 2 exit
if %input% GEQ 3 goto start
:create
cls
echo.
echo Welcome to Character Creation
echo.
echo Pick your race!
echo.
echo 1. Human
echo 2. Dwarf
echo 3. Elf
echo 4. Dragonborn
echo 5. Tiefling
echo.
set /p input=Choice:
if %input%==1 goto createHuman
if %input%==2 goto createDwarf
if %input%==3 goto createElf
if %input%==4 goto createDragonborn
if %input%==5 goto createTiefling
goto create
:createHuman
cls
echo.
echo You have chosen Human as your race!
echo.
echo Choose your class
echo.
echo 1. Fighter
echo 2. Ranger
echo 3. Rogue
echo 4. Wizard
echo.
set /p input=Choise
if %input%==1 goto humanFighter
if %input%==2 goto humanRanger
if %input%==3 goto humanRogue
if %input%==4 goto humanWizard
goto createHuman
:humanFighter
cls
echo.
echo You have chosen Fighter as your class!
echo.
echo Choose your weapon
echo.
echo 1. Battleaxe 1D8 Slashing
echo 2. Longsword 1D8 Slashing
echo 3. Rapier 1D8 Piercing
echo.
set /p input=choise
if %input%==1 goto humanFighter1
if %input%==2 goto humanFighter2
if %input%==3 goto humanFighter3
goto humanFighter
:humanfighter1
set lvl1=1
set exp1=0
set expmax1=300
set gp1=10
set hp1=12
set ac1=15
set profbonus1=2
set str1=4
set dex1=1
set con1=2
set int1=0
set wis1=2
set cha1=2
cls
echo.
echo To find your stats open your character sheet labeled humanfighter1_cs.txt
echo.
echo What's your name?
echo.
set /p name1=Enter:
goto hf1main
:hf1main
cls
echo.
echo %name1% Human Fighter
echo Lvl: %lvl1% Money:%gp1%
echo Hit Points: %hp1%/12
echo Armor: Breastplate Armor Class: %ac1%
echo Exp: %exp1%/%expmax1%
echo Weapon: Battleaxe 1D8 Slashing
echo Stat Modifiers:
echo Strength: +%str1%
echo Dexterity: +%dex1%
echo Constitution: +%con1%
echo Intelligence: +%int1%
echo Wisdom: +%wis1%
echo Charisma: +%cha1%
echo -------------------------------------
echo 1) Continue
echo 2) Exit
echo.
set /p input=Enter:
if %input%==1 goto hf1continue
if %input%==2 exit
I expect it to create the batch file after creating an account so that you can log in later.
For your menus, I would like to introduce you to choice.exe as an alternative to Set /P. It is far better to use it when input must be any one of a small set of known values. Set /P allows the end user to enter nothing or anything, and in order to maintain control you need to build in some input verification mechanism. To find out how choice.exe works, open a cmd.exe window and enter choice /? at the prompt.
Here is a rewritten example snippet of your script, (lines 1-43) to hopefully explain why:
#Echo Off
Title Lost Mine of Phandelvor
:EnterGame
ClS
Echo(
Echo Welcome to Lost Mine of Phandelvor
Echo ----------------------------------
Echo(
Echo 1. Create Account
Echo 2. Login
Echo 3. Exit
Echo(
Choice /C 123
If ErrorLevel 3 Exit /B
If ErrorLevel 2 GoTo Login
:CreateUser
ClS
Echo(
Set "username1="
Set /P "username1=What would you like your Username to be? "
If Not Defined username1 GoTo CreateUser
:CheckForSpaces
If Not "%username1: =%"=="%username1%" (
Echo Sorry you can not use spaces in your Username.
Choice /M "Is %username1: =%" okay"
If ErrorLevel 2 GoTo CreateUser
)
If Exist "%username1%.bat" GoTo :Login
Echo(
Set "password1="
Set /P "password1=What would you like your Password to be? "
However, before you continue with your script, based upon what I said about using Set /P. The end user can currently enter anything they want as username1. We've already checked for no entry and for spaces, but you're also saving the name as a filename too, %name%.bat. Along with the decimal character codes 0 through 31, Windows filenames cannot contain any of the following characters, \/:*?"<>|, so you'd need to incorporate further verification of username1. This verification procedure would need to be implemented before line 31 of the code above.
Before you do so however, you may want to consider changing your methodology and not saving the Username to the name of a file. The reason for this is that you'd also be wise not to use filenames ending with a ., or any named CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9 either. So you would further need to include those verification checks of the input too.
Don't forget, you'll probably want to include a verification method for input entries to the %password1% prompt too!
Given the complexity involved with user input and Set /P you can see why I have recommended choice.exe as a control measure for your menus.
Ooh - so many errors!
First, add an extra line setlocal enabledelayedexpansion directly after the #echo off line. This has two effects - first, when your batch ends, your environment is restored to its original condition so that you don't get confused with variables that have been established by prior runs. second, it turns on delayed expansion mode - which is where the !variable! syntax you are using is activated, otherwise ! is simply an ordinary character.
Next, having accepted input from the ketboard with a set /p, you have no idea whether the user entered. In your validation if statements, use if "%var%"=="value" which overcomes most input problems.
Next, the syntax SET "var=value" (where value may be empty) is used to ensure that any stray trailing spaces are NOT included in the value assigned.
And a little tip for games that need a save/restore feature:
If you reserve a character as a prefix for variables-you-want-to-save (eg all variables I want to save/reload start with #) then all you need to save a game is
set #>"mygamefile.txt"
and all you need to reload a game is
for /f "usebackqdelims=" %%a in ("mygamefile.txt") do set "%%a"
To zap all # variables (useful before reloading a game) use
for /f "delims==" %%a in ('set # 2^>nul') do set "%%a="
You should look at the thousands of code examples here on SO to find out how to use subroutines - you appear to be using "spaghetti code".
This code may help with your password-checking:
for /f "tokens=1,2" %%a in (passwordfilename) do if "%%a"=="%playername%" set "playerpass=%%b"
if "%playerpass%"=="%enteredpass%" goto gameon
This uses a single password file of the form
player1 password1
player2 password2
If player1 changes password, then append the new data to the file like this:
player1 password1
player2 password2
player1 newpassword
and the above for /f construct will then set playerpass to the last occurrence of player1 found.
This should provide you with a start and obviate your need for a subsidiary batch file. You'll have enough on your plate implementing these suggestions, but you should be able then to see the wood for the trees.
And implement changes one at a time, then test and debug them. Small steps will make the process a lot easier.
I'm using the same thing in my game. You need 2 functions, 1 to load and 1 to save. The save function should look something like this:
:: My save thing
:save
(
echo %var1%
echo %var2%
) > save.sav
and the loading portion should look something like this:
< save.sav (
set /p var1=
set /p var2=
)
also, one major recommendation, put all your scripts into separate files and folders. Like a normal game, example:
- MainGame
- Launcher.bat
- Resources
- Scripts
- Save.bat
- Load.bat
- Fight.bat
- Assets
- Title.txt
this is a similar structure to what I used in my game.
I've seen it done before on someone else's Batch program, so I'm sure it's possible. Every time I launch my program I run a series of lines of code such as:
set/a num=0
set/a tog=1
set/a ran=%random% %%10 +1
However, I would like for certain variables to stay around, even after the program is closed. I need scripts that can:
Write in a separate document the values of certain variables
Check that document for values at any point in any usage session
Thanks in advance!
You need a save system like so:
(
echo %VARIABLE1%
echo %VARIABLE2%
echo %VARIABLE3%
echo %VARIABLE4%
echo %VARIABLE5%
) > LOGS.prgmsav
The file extension can be .txt or something weird like .nerfguns, to load LOGS.prgmsav:
< LOGS.prgmsav (
set /p VARIABLE1=
set /p VARIABLE2=
set /p VARIABLE3=
set /p VARIABLE4=
set /p VARIABLE5=
)
The VARIABLE is any variable, you can save as many as you want! I hope I helped!
I am trying to save a batch variable into a text file. I currently have this code:
#echo off
Set var=6
#echo %var%>txt.txt
For /f "tokens*" %%i in (txt.txt) do #echo %%i
Pause
It's supposed to save the 6 into the variable var and then write the variable in a text file. I want to do this to save user input into a text file so that when the batch program is terminated it will hold the variables.
There is a little problem with redirection. You are redirecting a "stream"; they are numbered 0-9. 0 is for "Standard Input" (STDIN), 1 is for "Standard Output" (STDOUT), 2 is for "Error Output" (STDERR).
If you use the redirection symbol > without a stream number, it defaults to "1".
So echo text>txt.txt is just an abreviation for echo text 1>txt.txt
Now it's getting tricky: echo 6>txt.txt won't echo "6" to the file, but tries to redirect "Stream 6" (which is empty) to the file. The Standard Output echo is off goes to the screen, because "Stream1" is not redirected.
Solution:
If you try to redirect a number or a string which ends with a number, just use a different syntax:
>txt.txt echo 6
Use the set command to get the contents of a file:
set /p var=<filename
Use the echo command to put into a file:
#echo Contents Of File > "FileName"
To append another line to the end of the file, use:
#echo Contents Of File >> "FileName"
Also, put the commands on separate lines or use '&&' between them on the same line.
I am trying to create a bat file that is in essence a database. I want to be able to enter information that is tied to a single record. When I enter a record, I want to be able to look up the record by the card number assigned to it. The code I have now doesn't really work due to the fact that the variables are not being stored properly.
This is my code:
Color 5F
#echo off
:start
cls
echo ==========================================
echo Gift Card
echo ==========================================
echo.
echo What would you like to do?
echo.
echo 1 Add Card
echo 2 Check Information
echo 3 Edit Card Balance
echo 4 Delete Card
echo.
set /p choice=Please enter choice:
if /I %choice%==1 goto 1
if /I %choice%==2 goto 2
:1
echo.
set /p var=Enter Card Number:
set /p val=Enter Amount:
set /p fname=Enter First Name:
set /p lname=Enter Last Name:
set /p cbal=Enter Current Balance:
set /p diss=Enter Date issued:
#echo set %var%=%val%=%fname%=%lname%=%cbal%=%diss% > %var%.bat
echo.
echo The data has been stored!
pause
goto start
:2
echo.
set /p var=Please enter card number:
setlocal enabledelayedexpansion
call %var%.bat
echo !%fname%! !%lname%!'s !%var%! card has $!%cbal%! on it as of !%diss%!!
pause > nul
goto start
I have tried to send the variables separately and altogether and none have worked. I am thinking it is because I do not have the delayed expansion sytax correct.
Any help is very appreciated!
Your problem seems to lie where you generate the batch file to fill the variables... You generate only one line, which does not actually assign anything to any of the variables you need.
Try changing
#echo set %var%=%val%=%fname%=%lname%=%cbal%=%diss% > %var%.bat
to be
#echo set var=%var% > %var%.bat
#echo set val=%val% >> %var%.bat
#echo set fname=%fname% >> %var%.bat
#echo set lname=%lname% >> %var%.bat
#echo set cbal=%cbal% >> %var%.bat
#echo set diss=%diss% >> %var%.bat
This should allow your variables to be loaded back properly.
Also, change
echo !%fname%! !%lname%!'s !%var%! card has $!%cbal%! on it as of !%diss%!!
to read
echo %fname% %lname%'s %var% card has $%cbal% on it as of %diss%!
You should never use both ! and % to surround variables in a batch file, only one or the other. % should be used in most cases; ! should be used when you need to read a variable inside a multi-line "code block" (for example, the result of an if statement or the body of a for loop) which is surrounded by parentheses.
Some more advice:
You can put setlocal delayedexpansion just once in the beginning of the file, right after #echo off. However, you are not doing anything in this program (yet, at least) to need delayed expansion. Delayed expansion is used to enable accessing variables with the ! symbol and is only useful inside multi-line statement bodies surrounded by parentheses. Because of that, you should get rid of it completely unless/until you actually need it, as it can cause other problems.
There is no need for the "#" symbol in any command after you call #echo off (but it won't break anything). The # symbol simply suppresses echoing of the command which it precedes, but it is redundant because all commands are silenced by default after you call echo off. For this reason, it is important to only use it on the first line when calling #echo off, so that the user does not see that command echoed.
Creating a batch script in Windows XP. Here's a snippet of code I'm having problems with:
::==============================================================::
::How many scripts are included in this program?
SET NumOfScripts=4
::==============================================================::
:mainmenu
CLS
ECHO [MAIN MENU]
ECHO Please choose from the following options to run a particular script:
set /p choice="[1] SCRIPT1.bat | [2] SCRIPT2.bat | [3] SCRIPT3.bat | [4] SCRIPT4.bat : "
IF %choice% EQU 1 CALL :SCRIPT1
IF %choice% EQU 2 CALL :SCRIPT2
IF %choice% EQU 3 CALL :SCRIPT3
IF %choice% EQU 4 CALL :SCRIPT4
REM Wrong Choices
IF %choice% GTR %NumOfScripts% (
(ECHO You have entered an invalid option. Please press any key to be taken back to the main menu.) & PAUSE & GOTO:mainmenu
)
IF %choice% LEQ 0 (
(ECHO You have entered an invalid option. Please press any key to be taken back to the main menu.) & PAUSE & GOTO:mainmenu
)
ECHO You have entered an invalid option. Please press any key to be taken back to the main menu
PAUSE & GOTO:mainmenu
Looking under REM Wrong Choice, the first two arguments work as they should, however, if the user enters in no value (just presses the enter key) it automatically terminates the script. I've added IF NOT DEFINED choice and that doesn't work... I also tried IF [%choice%]==[] and IF [%choice%] EQU [] and those don't work either.
Here's the funny thing... you enter an invalid digit, say 5 or -1, it will give the echoes and go back to the main menu as it should... THEN if you just press enter without a value inserted, it will echo and go back to the main menu as it should.
My question is how do you get it to recognize that the user did not enter a value for set /p on the first go?
You can initialize choice to some invalid value before set /p, e.g.:
SET choice=none
To print the appropriate error message, you can do
IF %choice% EQU none (
(ECHO You did not select an option.) & PAUSE & GOTO:mainmenu
)
Set /p doesn't change the content of a variable, if the user doesn't enter text.
So you can simply set your variable to nothing to detect if the user enter anything.
Set "choice="
Or you can use the errorlevel, as it is set to 1 if the input is empty
But be careful, as it doesn't reset it to 0. So you have to force it yourself before.
cd.
Set /p choose=
If %errorlevel%==1 goto empty
And you should use the variables with delayed expansion, as it is always safe.
Else a user can break your script with input like "&exit"