4
::Compare with available valid arguments
FOR /L %%i IN (1,1,!avArgc!) DO (
    FOR /L %%j IN (1,1,!argc!) DO (
        IF !avArgv[%%i]!==!argv[%%j]! (
            echo Match: !avArgv[%%i]!

            ::Check the next option
            SET /A nextArg=%%j
            SET /A nextArg+=1
            FOR /L %%n IN (!nextArg!,1,!nextArg!) DO ( 
                IF !nextArg! LEQ !argc! ( 
                    echo next arg: !argv[%%n]!
                    call :CheckSubOption
                )
            ) 
        )
    )
)

In my above code example - How do I take for loop variable like %%j and increment itself within the for loop like this %%j++ ? Current solution that I have (which is messy and I don't like it) is to create a new variable and set it to the value of %%j and then increment that variable and start using that variable like this:

::Check the next option
SET /A nextArg=%%j
SET /A nextArg+=1
Shady Programmer
  • 794
  • 4
  • 9
  • 22
  • 4
    `%%j` is parsed with the `for` loop. That means, inside the loop it's already parsed, so it's a fixed value, not a variable that you could change. I'm afraid, you have to live with that messy new variable. – Stephan Mar 16 '16 at 15:31
  • 2
    `SET /A nextArg=%%j`, the `/a` isn't needed. It shouldn't hurt, but should be avoided. Also, i suspect this was put in for our sake, but with `::Check the next option`, never put a `::` command in a code block, just `rem`. There could be ways to let you change it by calling an outside label with referenced variables, but honestly, it will be even messier than adding new variables. – Bloodied Mar 16 '16 at 18:00
  • Thanks Stephen that answered my question. @Arescet `::` and `rem` are interchangable therefore it's okay to use them inside the code block. The code works as it should with my `::` way of adding comments plus `::` is easier to spot. – Shady Programmer Mar 18 '16 at 15:20
  • 1
    @ShadyProgrammer no, `rem` is an actual command, `::` is a label with an invalid starting character. http://www.robvanderwoude.com/comments.php , http://ss64.com/nt/rem.html and http://stackoverflow.com/questions/12407800/which-comment-style-should-i-use-in-batch-files show the issues with `::`, even though it's faster it can be very unpredictable having it in a code block. – Bloodied Mar 18 '16 at 17:41

2 Answers2

1

The general solution for thoses case is to not rely on blocks inside loops/if but instead to use subroutines where you are not blocked by the level of evaluation.

FOR /L %%i IN (1,1,!avArgc!) DO call :Loop1 %%i
goto :EOF

:Loop1
FOR /L %%j IN (1,1,!argc!) DO call :Loop2 %1 %%j
goto :EOF

:Loop2
IF !avArgv[%1]!==!argv[%2]! (
            echo Match: !avArgv[%1]!

            ::Check the next option
            SET /A nextArg=%2+1
            call :CheckOpt %nextArg%
)
goto :EOF

:CheckOpt
IF %1 LEQ %argc% ( 
    echo next arg: !argv[%1]!
    call :CheckSubOption
)
dolmen
  • 8,126
  • 5
  • 40
  • 42
  • Good suggestion, although I feel like it will make my code go from messy to different kind of messy I'll use it to tidy up my overall code structure. Thank you. – Shady Programmer Mar 18 '16 at 15:12
1

Observing your code and your intention, it would seem that you would want to skip numbers during the loop structure. The way you want to change it though would be destabilizing. In most scripting languages such as matlab,bash, and batch, the variable that is used in for-loops serves as a frame of reference within the loop. When you tell the code to run a particular for-loop, it will run that computation regardless if the parameters of it changed. A real world example of this is the professor who is using outdated figures to solve a problem and it isnt until the next day he receives the new figures. The professor cant change his answer accordingly because he doesnt have the new data yet.

This does not mean this problem is unsolvable. In fact there are a variety of ways to approach this. The first one which is a little more complicated involves a nested For structure.

@echo off
set /p maxLength=[Hi times?]
set skip=0

FOR /L %%i IN (1,1,%maxLength%) DO (call :subroutine %%i)

echo alright im done.
pause 
GOTO :eof

rem the below code uses a for loop structure that only loops 1 time based on the passed argument from the overall for loop as so to make changes to how its run.

:subroutine
set /a next=%1+%skip%
 FOR /L %%r IN (%next%,1,%next%+1) DO (call :routine %%r)
 GOTO :eof

:routine
if %1==3 (set /a skip=1)
echo %skip%
echo %next%
echo %1
pause
GOTO :eof

When running the program, the variable next will skip the value of 3 if the maxlength variable is greater than 3.

  • The reason this is so is because the nested for-loop only runs once per iteration of the overall for loop

. This gives the program time to reset the data it uses, thanks to the call command which serves as a way to update the variables. This however is extremely inefficient and can be done in much less lines of code.

The second example uses GOTO's and if statements.

@echo off
set jump=1
:heyman
set /A "x+=%jump%"
if %x%==4 (set /A "jump=2")
echo %x%
if %x% LSS 10 goto heyman
echo done!

This code will essentially echo the value of x thats incremented each time until it reaches the value of 10. However when it reaches 4, the increment increases by 1 so each time it runs the loop increments the x value by 2. From what you wanted, you wanted to be able to change the way the value of %%j increments, which can not be done as %%j is a statement of where the for-loop is in its computation. There is no difference in what can be accomplished with for-loops and goto statements except in how they are handled.

While i unfortunately don't have the correct form of your code yet, i know that code examples i have given can be utilized to achieve your particular desire.

Jouster500
  • 762
  • 12
  • 25
  • Thank you, It seems like my final solution is going to be as messy as it appeared to be prior to asking this question here. You have answered my question with that sentence marked in bold text and additionally gave me idea to go and experiment with GOTO & IF statments combined together instead of a for loop. – Shady Programmer Mar 18 '16 at 15:09
  • 1
    You're welcome. Remember, sometimes a different set of code may better suit your needs. Its not always a good idea to force a command into doing something its not specifically built to handle. – Jouster500 Mar 19 '16 at 22:59
  • If you are looking to modify variables during a for-loop and to update promptly outside, remember that a for loop is only locally run. You need to run `setlocal enabledelayedexpansion` at the beginning of your code to allow variables to be update based on running functions. Thus if you have a for loop that runs a `set n+=1`, you can use `!n!` to call the newly updated variable during the for loop. – Jouster500 Mar 21 '16 at 15:47
  • Thank you for that information, if you look at my code you'll notice I'm already using and I'm aware of delayed expansion of variables like `!n!`. However now that you've mentioned that - I was going to ask another question on SO to find out if there's a way of doing this: `!arr[!count!]!` - I want to expand `count` inside the `arr[]` variable which I'm expanding, I've found a workaround on how to achieve that goal but again it's ugly looking and I want to know if there's a better way. – Shady Programmer Mar 22 '16 at 13:06
  • 1
    Look no further. http://stackoverflow.com/questions/10166386/arrays-linked-lists-and-other-data-structures-in-cmd-exe-batch-script – Jouster500 Mar 22 '16 at 13:16
  • Thank you, It seems that there is no elegant way of doing what I want. In the answer in the link that you've sent the guy outlines two 'hacks' on how to do it, first one (which I thought I've invented) is using a `FOR` loop and the second one is using a `call` command. Batch scripting is seriously crippled when you think about it. – Shady Programmer Mar 22 '16 at 14:05
  • 1
    Its not as syntactically elegant as other scripting languages such as bash scripting, but its simplicity and integration into other microsoft features make it a somewhat useful language to learn. These can be things such as simulated key presses or a playlist of youtube videos if you dont have an account. And considering that most people use windows (proof for the number of viruses it sees), batch scripts are largely portable and can be modified to be as good as any other language. – Jouster500 Mar 22 '16 at 14:10