2016-03-16 115 views
3
::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 
       ) 
      ) 
     ) 
    ) 
) 

在我上面的代碼示例中 - 我如何獲取循環變量,如%%j,並在for循環中像這樣增加自己%%j++?我有當前的解決方案(這是凌亂的,我不喜歡它)是創建一個新的變量,並將其設置爲%%j值,然後遞增變量並開始使用像這樣的變量:如何在批處理腳本中增加循環變量?

::Check the next option 
SET /A nextArg=%%j 
SET /A nextArg+=1 
+4

'%% j'用'for'循環解析。這意味着,在循環內部它已經被解析了,所以它是一個固定值,而不是你可以改變的變量。恐怕,你必須忍受那個混亂的新變數。 – Stephan

+2

'SET/A nextArg = %% j','/ a'不需要。它不應該傷害,但應該避免。另外,我懷疑這是爲了我們的緣故,但是用'::檢查下一個選項',不要在代碼塊中放置'::'命令,只是'rem'。可以通過調用具有引用變量的外部標籤來改變它,但實際上,它會比添加新變量更加混亂。 – Bloodied

+0

謝謝Stephen回答我的問題。 @Arescet'::'和'rem'可以互換,因此可以在代碼塊中使用它們。代碼的工作方式與我的'::'添加註釋的方式一樣,加上'::'更容易被發現。 –

回答

1

觀察你的代碼和你的意圖,你似乎想在循環結構中跳過數字。你想改變它的方式會破壞穩定。在大多數腳本語言中,如matlab,bash和batch,在for循環中使用的變量在循環內充當參考框架。 當你告訴代碼運行一個特定的for循環時,它將運行該計算,而不管它的參數是否改變。這方面的一個真實世界的例子是使用過時的數字來解決問題的教授,直到第二天他才收到新的數字。教授不能相應地改變他的答案,因爲他還沒有新的數據。

這並不意味着這個問題是無法解決的。事實上,有多種方法可以解決這個問題。第一個更復雜一點的是嵌套的For結構。

@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 

運行程序時,變量next將跳過的3值,如果maxlength變量大於3.

  • 其原因是這樣是因爲嵌套for循環只能運行一次 每次迭代的整體for循環

。由於call命令用作更新變量的一種方式,因此程序有時間重置其使用的數據。然而,這是非常低效的,可以用少得多的代碼行來完成。

第二個示例使用GOTO和if語句。

@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! 

,直到達到10分的值。該代碼將基本上回聲每次遞增X這就是的值。但是,當它到達如圖4所示,由1增量增加,因此每次運行循環遞增的x值由你想要的,你想能夠改變%%j增值的方式,這是不可能完成的,因爲%%j是for循環在其計算中的位置的聲明。 for循環和goto語句除了處理方式外,沒有什麼區別。

雖然我很遺憾沒有正確的代碼形式,但我知道我給出的代碼示例可以用來實現您的特定願望。

+0

謝謝,看來我的最終解決方案會像在這裏問這個問題之前那樣混亂。您用粗體文本標記了句子,回答了我的問題,並且還給了我一些想法,讓我去試驗GOTO&IF結合在一起而不是for循環。 –

+1

不客氣。請記住,有時一組不同的代碼可能更適合您的需求。它並不總是一個好主意,迫使一個命令做一些非專門處理的事情。 – Jouster500

+0

如果您希望在for循環中修改變量並在外部及時更新,請記住for循環只能在本地運行。您需要在代碼的開頭運行'setlocal enabledelayedexpansion',以便根據運行功能更新變量。因此,如果你有一個運行'set n + = 1'的for循環,你可以使用'!n!'在for循環中調用新更新的變量。 – Jouster500

1

這種情況的一般解決方案是不依賴循環/塊內的塊,而是使用不受評估級別阻塞的子例程。

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 
) 
+0

嵌套for循環結構是否正確? – Jouster500

+0

好的建議,雖然我覺得它會讓我的代碼從雜亂到不同的雜亂,我會用它來整理我的整體代碼結構。謝謝。 –