2014-10-11 72 views
0

代碼:批次/ a不存儲值

@echo off 
set /a x=5 
set /a TNUM=%x%-3 
echo %TNUM% 
pause 

,輸出是:

ECHO is off 

那麼,如何解決這個問題?

下面是完整的代碼:

@echo off 
setlocal enableextensions 
set /a COLUMNS=60 
set /a ROWS=40 
mode con: cols=%COLUMNS% lines=%ROWS% 

:main 
    set /a xpos=5 
    set /a ypos=5 

    call:displayScreen 

    pause >nul 
    goto :eof 

::FUNCTIONS:: 
:displayScreen 
    set /a TEMPR=%ROWS%-3 
    for /l %%c in (1,1,%COLUMNS%) do echo|set /p=# 
    for /l %%r in (1,1,%TEMPR%) do (
     echo|set /p=# 
     if %%r==%ypos% (
      set /a TNUM=%xpos%-3 
      echo %TNUM% 
      for /l %%t in (1,1,%TNUM%) do echo|set /p=A 
      echo|set /p=o 
      set /a TNUM=%COLUMNS%-%xpos%-1 
      for /l %%t in (1,1,%TNUM%) do echo|set /p=A 
     ) else (
      set /a TNUM=%COLUMNS%-2 
      for /l %%t in (1,1,%TNUM%) do (
       echo|set /p=A 
      ) 
     ) 
     echo|set /p=# 
     echo. 
    ) 
    for /l %%c in (1,1,%COLUMNS%) do echo|set /p=# 

的主要問題是在顯示屏幕的功能。它應該打印屏幕,並在我給出的兩個座標處有x。我把回聲%TNUM%,所以我可以看到它是什麼,它總是等於「」。

+0

你試過添加'setlocal ENABLEDELAYEDEXPANSION'嗎?然後用'!x!'替換'%x%'? – 2014-10-11 04:50:57

+0

我只是學習批次,所以我不太瞭解。我如何適應我的代碼?你介意編輯它,以便我可以看到嗎? – Twonty2 2014-10-11 04:52:28

+3

完美地爲我工作。您是否通過剪貼粘貼發佈? – Magoo 2014-10-11 05:13:03

回答

2

主要有三種方式獲得指示行爲

- 可變的擴展問題。在批處理文件中,行或行塊(括號中的一組行)被解析,執行,然後在下一行/塊上重複該操作。

在分析階段所有讀變量的操作(任何%var%)從代碼被去除,與存儲在變量的值替換它們之前開始執行的代碼行/塊。

因此,如果在行/塊內部變量的值發生變化,則在執行階段,不能在同一行/塊內重疊/檢索此值。爲什麼?因爲在行/塊中沒有讀取操作來檢索變量的值。此代碼

set x=0 
if 1==1 (
    set x=1 
    set y=%x% 
) 
echo x=%x% y=%y% 

迴音必安慰x=1 y=0爲什麼?當的代碼if塊被解析(完整的塊),則讀取操作(=%x%)其中在分析時替換爲在分析時的變量內的值,並執行的代碼是

if 1==1 (
    set x=1 
    set y=0 <- Read operation in x replaced with its value at parse time 
) 

即,存儲在x中的更改值無法檢索。

這種情況通常使用延遲擴展來解決。這是一種可以用命令setlocal enabledelayedexpansion激活的行爲,它允許程序員在需要的地方更改,訪問從%var%!var!的變量內容的語法,向分析器指示變量的擴展(替換讀取操作的變量值)必須延遲到執行階段。在所提出的樣品應該是

setlocal enabledelayedexpansion <- delayed expansion enabled 
set x=0 
if 1==1 (
    set x=1 
    set y=!x! <- Read operation delayed 
) 
echo x=%x% y=%y% 

- 空間。與變量聲明習慣性的問題是

set /a TNUM = %x%-3 
      ^.......This value is included in the variable name 

的空間被包含在變量名,並且這不是變量的名稱相呼應%TNUM%失敗,它被命名爲%TNUM %

我忘記和@jeb糾正意見,同時setset /p出現此行爲,這會不會在使用set /a發生。在這種情況下,將使用具有不同規則的解析器(例如,它允許變量引用無需事先展開),並且指定的空間將被抑制。

- 您的機器默認情況下已禁用擴展功能。如果擴展名是殘疾人,set /a將不工作,並且沒有值將被分配給變量

@echo off 
    setlocal enableextensions 
    set /a x=5 
    set /a TNUM=x-3 
    echo %TNUM% 

總結,以執行線echo %TNUM%並獲得指示ECHO is off必要的是,當行被解析TNUM是未定義或僅包含空格或製表符。

作爲先驗,當行被執行時,一個值被分配給變量(至少-3),看來你的問題是情況1(回聲值被替換之前執行)或者情況3(由於set操作失敗,您無法回顯)。

編輯隨着所有的代碼發佈,問題是延遲擴展。

@echo off 
    setlocal enableextensions enabledelayedexpansion 
    set /a COLUMNS=60 
    set /a ROWS=40 
    mode con: cols=%COLUMNS% lines=%ROWS% 

:main 
    set /a xpos=5 
    set /a ypos=5 

    call :displayScreen 

    pause >nul 
    goto :eof 

::FUNCTIONS:: 
:displayScreen 
    set /a TEMPR=%ROWS%-3 
    for /l %%c in (1,1,%COLUMNS%) do echo|set /p=# 
    for /l %%r in (1,1,%TEMPR%) do (
     echo|set /p=# 
     if %%r==%ypos% (
      set /a TNUM=%xpos%-3 
      for /l %%t in (1,1,!TNUM!) do echo|set /p=A 
      echo|set /p=o 
      set /a TNUM=%COLUMNS%-%xpos% 
      for /l %%t in (1,1,!TNUM!) do echo|set /p=A 
     ) else (
      set /a TNUM=%COLUMNS%-2 
      for /l %%t in (1,1,!TNUM!) do (
       echo|set /p=A 
      ) 
     ) 
     echo|set /p=# 
    ) 
    for /l %%c in (1,1,%COLUMNS%) do echo|set /p=# 
+1

當使用'/ a'選項時,空間問題不存在,只有沒有選項或使用'/ p' – jeb 2014-10-11 08:46:18

+0

@jeb,argh,我忘記了!而且我也忘記了第3點。 – 2014-10-11 10:12:01

+0

我添加了完整的代碼並完成了setlocal enableextentions。我可能做了一些可怕的錯誤。感謝你的幫助! – Twonty2 2014-10-11 15:38:17

1

看起來它並不等待評估%x%。因此,您可以添加ENABLEDELAYEDEXPANSION,以便它將等待評估x,以便在數學運算期間對其進行初始化。

@echo off 
setlocal ENABLEDELAYEDEXPANSION 
set /a x=5 
set /a TNUM=!x!-3 
echo !TNUM! 
endlocal 
pause 
+0

噢好吧。這就說得通了。我會稍後再嘗試一下,謝謝! – Twonty2 2014-10-11 04:55:17

+0

儘管'!x!'可以是set/a命令中的簡單變量名'x',但在上面的完整代碼中,這是正確的 - 您是否實現了此答案?除非你真的需要覈實變量,否則你可以離開'endlocal'。 – foxidrive 2014-10-11 15:43:27

0

在塊語句(a parenthesised series of statements),所述整個塊被解析並然後執行。塊中的任何%var%將在該塊被解析時被該變量的值取代 - 在塊被執行之前。

由於for...%%r...循環執行的代碼(以下的do通過對匹配)(),那麼塊內出現的任何%tnum%將通過tnum值替換當環路被解析的塊。 Tnum在塊啓動時沒有任何值,所以這就是顯示的內容。

tnum被設置環路內,這樣以來你在程序開始有enabledelayedexpansion設置爲ON在setlocal enabledelayedexpansion語句,你需要使用!tnum!代替循環內的%tnum%,以便在其更改時訪問tnum的值。