Batch Addition From File (+1) Rewrite - batch-file

I'm making a batch game, that counts a highscore in a separate file called "Score.txt".
In that file, it reads a number, but when you win the game I want it to be overriden with the next highest number. E.G... 0 is the number, I won the game, now it reads 1.
So far this is my code for the highscore...
:Score
SetLocal EnableDelayedExpansion
set score=
for /F "delims=" %%i in (Score.txt) do set score=!score! %%i
set /a %score%=%score%+1
echo %score% >score.txt
exit
But "Score.txt" only reads if ECHO is on, after I win.

I think this is what you are trying to do:
:Score
SetLocal EnableDelayedExpansion
set score=
for /F "delims=" %%i in (Score.txt) do set score=%%i
set /a score=!score!+1
echo !score! >score.txt

James L.'s answer certainly solves the problem, but doesn't explain why the original didn't work.
As James L. pointed out in his comment, the !score! is not needed in the FOR statement, though it is not doing any harm since it is undefined.
Delayed expansion is not needed for this problem.
The reason the original code failed was the first expansion in set /a %score%=%score%+1. That statement will create a variable with a number as the name. It should have read set /a score=%score%+1, or set /a score=score+1, or set /a score+=1.
There is an alternate to using FOR /F
#echo off
set "score="
<"Score.txt" set /p "score="
set /a score+=1
>"Score.txt" echo %score%

Related

Formatting generated numbers in a .bat file

Forgive me if there is a simple answer to this, I'm new to all of this.
The below .bat script generates a list of numbers depending on how many numbers you want.
However what I would like is to format the numbers it generate.
For example, if I input 20, instead of it coming out 1, 2, 3 etc. I would like it to come out as 001, 002... 020.
Is this possible? Am I missing something obvious?
Many Thanks.
#echo off
setlocal EnableExtensions
:start
cls
set /p loopcount= How Many Users?:
set "x="0"
:loop
set /a "x+=1"
echo %x%
set /a loopcount=loopcount-1
if %loopcount%==0 goto exitloop
goto loop
:exitloop
pause
goto start
just implementing SomethingDark's suggestion (and a minor change in the logic of the loop):
set /p "loopcount= How Many Users?: "
set "x=1000"
:loop
set /a x+=1
echo %x:~-3%
set /a loopcount-=1
if %loopcount% gtr 0 goto :loop
echo loop finished.
(btw: your set "x="0" has a quote too much (probably a typo)
Here's a quick example batch file which uses powershell for your leading zeroes.
I have used a for loop as the looping mechanism.
#Echo Off
SetLocal EnableExtensions
:AskNum
Set "num=1"
Set /P "num=how many users?"
Set num | findstr.exe /RX "^num=[123456789][0123456789]*$" 1>NUL || GoTo AskNum
For /F %%G In ('powershell.exe "1..%num% | %% ToString User000"') Do Echo %%G
Pause
This script will not continue unless the end user inputs an integer, without a leading 0, and which is a minimum value of 1. Here you can modify the Echo command in Do to an alternative, for example net.exe User %%G /Add, or if you wish, to a parenthesized sequence of commands. In each case %%G will contain the returned string with the incremented three digits.This version prepends each three digit number sequence with an additional string, (User), but that can simply be deleted or replaced if/as required.
#ECHO OFF
SETLOCAL enabledelayedexpansion
SET /p "lastnum= How many numbers? "
SET /a lastnum+=1000
FOR /L %%e IN (1001,1,%lastnum%) DO SET /a num=%%e&ECHO !num:~-3!
GOTO :EOF
No need for complication

Fetch the max column count present in a file using batch (.BAT) programming

I have a test.csv file which has data something like this.
"a","usa","24-Nov-2011","100.98","Extra1","Extra2"
"B","zim","23-Nov-2011","123","Extra22"
"C","can","23-Nov-2011","123"
I want to fetch the maximum number of columns in this file (i,e 6 in this case) and then store this in a variable.
Like
Variable=6
I'm aware that this can be acheived in scripting as I have some basic knowledge about scripting. But I have zero programming knowledge in .BAT.
Please help me regarding this
#echo off
setlocal EnableDelayedExpansion
set variable=0
for /F "delims=" %%a in (test.csv) do (
set count=0
for %%b in (%%a) do set /A count=+1
if !count! gtr !variable! set variable=!count!
)
echo Variable=%variable%
This solution use the fact that strings enclosed in quotes in a FOR set are treated as individual items, so count they is very easy. For this reason, this method fail if there are wild-card characters ("*" or "?") in the lines.
If comma is your delimiter, maybe you could try to count the number of commas in every line and remember the biggest one (and increase it by one). (I assume, that commas are not in the strings)
count instances of a character in file per line : https://stackoverflow.com/a/7988661/2282321
edit:
I came up with following solution, please try it (assuming input file name with data to be 'a.txt'):
#echo off
set biggest_len=0
for /f "tokens=*" %%a in (a.txt) do call :processline %%a
echo %biggest_len%
goto :eof
:processline
set len=0
for %%b in (%*) do set /A len+=1
if %len% gtr %biggest_len% set /A biggest_len=len
goto :eof
:eof
sources I used to create solution:
Batch Script - Count instances of a character in a file
If greater than batch files
batch script - read line by line
#ECHO OFF
SETLOCAL
SET /a maxcols=0
SET /a mincols=999999
FOR /f "delims=" %%a IN (q28540735.txt) DO SET /a total=0&CALL :count %%a
ECHO maximum columns=%maxcols%
ECHO minimum columns=%mincols%
GOTO :EOF
:count
SET "$1=%~1"
IF DEFINED $1 SET /a total+=1&shift&GOTO count
IF %total% gtr %maxcols% SET /a maxcols=total
IF %total% lss %mincols% SET /a mincols=total
GOTO :EOF
I used a file named q28540735.txt containing your data for my testing.
Each line is presented to the subroutine count as comma-separated parameters, so if you set the total found to zero before each call, then it's a simple matter of counting the parameters. If the parameter presented is enclosed in quotes, then any commas and spaces within the quotes are processed as being part of the token, not separators in their own right.

Line reading program does not work

I have a program that reads the file and outputs a random file line number, but when it goes to output it, it just says "Echo is off" Is it possible to fix this?
Here is my code:
#echo off
setlocal enabledelayedexpansion
set Counter=1
for /f "tokens=* delims=" %%x in (Lists.txt) do (
set "Line_!Counter!=%%x"
set /a Counter+=1
)
set /a Counter=%random% * 100 / 32768 + 1
echo %Counter%
echo "%Line_!Counter!%"
::Just displays echo is off
pause
echo "!Line_%Counter%!" will work. (not very intuitive, but makes sense, if you think about it)
There are two problems in your code.
The first has been pointed by Stephan. If you read the answers to this question, you will see that the parser replaces variables referenced with percents before variables referenced with exclamation marks. So when the parsers tries to handle %Line_!Counter!%, !Counter! is still not replaced in the line so %Line_!Counter!% is an undefined variable and is replaced with nothing. The inverse (!Line_%Counter%!) works because when the parser reaches the line, the first substitution is the percent variable and the last the exclamation mark variable.
The second is a logic error. The line
set /a Counter=%random% * 100 / 32768 + 1
will not work as intended if the file has more or less than 100 lines. If it has more, the higher numbered lines will never be selected. If it has less lines, a high numbered non existing line can be selected and as it does no exist, you will again get an echo is off message trying to echo the variable.
#echo off
setlocal enabledelayedexpansion
set Counter=0
for /f "tokens=* delims=" %%x in (Lists.txt) do (
set /a Counter+=1
set "Line_!Counter!=%%x"
)
set /a "selected=%random% %% Counter + 1"
echo %selected%
echo "!Line_%selected%!"
pause

Comparisons returning incorrect value in batch

I have the code:
#echo off
set /p dec="Path? "
set patha="C:\Users\%username%\%dec%"
set /a i=2
setlocal EnableDelayedExpansion
:import
if "%i%"=="12" goto loopend
if "!patha:~-%i%,1!"=="." set ext="!patha:~-%i%!"
set /a i=%i%+1
goto import
:loopend
echo %ext%
pause
It loops through the code 10 times, but when I have it echo "!patha:~-%i%,1!" and it echoes "." it doesn't set the ext variable. Am I doing comparisons wrong?
Works happily or me in W7, although
FOR /f %%i IN ("%patha%") DO SET ext="%%~xi"
echo %ext%
would seem to do the same thing.
That is, assuming you want to extract the last n characters starting "."... (that's not clear)

batch programming

I am new in batch. Trying for some days to make something in batch but have a problem I cannot solve. I read a lot of your comments but did not find answer. Maybe you can help me?
The point is:
I input string from keyboard( e.g. 10 characters ). name of it is"allinputstring"
Calculate of length is ok ( by redirect in txt file and expand its bytes ). name "length"
Parse string in 10 pieces (strings) is ok.
So here is a problem, I want to echo these pieces, so I use next code, I use a counter to find out is the counter give me good count as output variable, and echo it to see on screen if it is good. Counter seems good, end echo of pieces strings is good enough. But I want to put in line 5. Variable count instead of "%%m", and cannot find a syntax way how to do it.
setlocal enabledelayedexpansion
for /l %%m in (1,1,!lenght!) do (
set /a count=0
set /a count=count+%%m
echo !count!!allinputstring:~%%m,1!
)
endlocal
please help me.
Try this:
#echo off &setlocal enabledelayedexpansion
set /a lenght=9
set "allinputstring=ABCDEFGHIJ"
for /l %%m in (0,1,%lenght%) do (
set /a count=0
set /a count+=%%m
echo !count! !allinputstring:~%%m,1!
)
endlocal
Output is:
0 A
1 B
2 C
3 D
4 E
5 F
6 G
7 H
8 I
9 J
#ECHO off
setlocal ENABLEDELAYEDEXPANSION
SET allinputstring=abcdefghijk
SET lenght=10
for /l %%m in (1,1,!lenght!) do (
set /a count=0
set /a count=count+%%m
FOR %%z IN (!count!) DO echo !count! !allinputstring:~%%z,1!
)
GOTO :eof
Does this do what you require?
So... to make COUNT show (I've assigned it to KOWNT, but the syntax endlocal&set count=%count% would assign it to COUNT instead)
I've changed the starting value of the FOR/L because character counting starts from character#0 in the string.
#ECHO off
setlocal ENABLEDELAYEDEXPANSION
SET allinputstring=abcdefghij
SET lenght=9
for /l %%m in (0,1,!lenght!) do (
set /a count=0
set /a count=count+%%m
FOR %%z IN (!count!) DO echo !count! !allinputstring:~%%z,1!
)
endlocal&SET KOWNT=%count%
ECHO Now KOWNT=%KOWNT% but count=%count% because we have exited the SETLOCAL
GOTO :eof
When the ENDLOCAL is encountered, the parser substitutes the CURRENT value of the variables in the line and THEN executes the line.
Hence, the line is executed as
endlocal&set KOWNT=9
since the value of count at the time is 9.
When the SETLOCAL is executed, all changes to the environment since the matching SETLOCAL are thrown away. The environment variables are restored to their state when the SETLOCAL was executed and count becomes empty again (as it was before the routine.) THEN the SET instruction is executed, which sets KOWNT to 9.

Resources