Windows批处理脚本中的变量本地化

Windows批处理脚本中的变量本地化

我声明并定义了 5 个字符串,然后通过函数调用对它们进行一些分析。第一个函数计算字符串的长度,第二个函数计算字符串中的空格数。最后两个函数尚未实现。当我运行批处理脚本时,我收到几个错误,提示“缺少操作数”。我认为问题与变量的本地化有关。有人能想出如何解决这个问题吗?除了启用扩展和延迟扩展之外,setlocal EnableExtensions EnableDelayedExpansion ... endlocal 行是否还会使块中的变量本地化?

@REM File:      String analysis.bat
@REM Author:    Jakob Kjeldberg Andersen

@echo off

setlocal EnableExtensions EnableDelayedExpansion

chcp 65001 > nul

color 0A

title String analysis

set /a Count=0

set /a Count+=1 & set String_!Count!="This is a test."
set /a Count+=1 & set String_!Count!="This_is_a_test."
set /a Count+=1 & set String_!Count!="        This is a test."
set /a Count+=1 & set String_!Count!="This is a test.        "
set /a Count+=1 & set String_!Count!="    This is a test.    "

set /a Start=1
set /a Step=1
set /a Stop=!Count!

set Separatorline=--------------------------------------------------------------------------------

echo !Separatorline! & echo. & echo Strings: & echo.

FOR /L %%X IN (!Start!,!Step!,!Stop!) do (

    echo %%X: !String_%%X! & echo.

)

echo !Separatorline! & echo. & echo Stringslengths: & echo.

FOR /L %%X IN (!Start!,!Step!,!Stop!) do (

    call :StringLength !String_%%X! , Length

    echo %%X: !Length! & echo.

)

echo !Separatorline! & echo. & echo Number of spaces in strings: & echo.

FOR /L %%X IN (!Start!,!Step!,!Stop!) do (

    call :SpaceCount !String_%%X! , NumberOfSpaces

    echo %%X: !NumberOfSpaces! & echo.

)

endlocal
 
pause&goto:eof

::==============================================================================

:StringLength StrVar , [RtnVar]

setlocal EnableExtensions EnableDelayedExpansion

set /a Length=0
set String="%~1#"

for %%P in ( 4096 2048 1024 512 256 128 64 32 16 8 4 2 1 ) do (

    if "!String:~%%P,1!" NEQ "" (
        
        set /a Length+=%%P      
        set String=!String:~%%P!

    )

)

endlocal & if "%~2" equ "" (echo !Length!) else set /a %~2=!Length!

exit /B 0

::==============================================================================

:SpaceCount StrVar , [RtnVar]

setlocal EnableExtensions EnableDelayedExpansion

set String="%~1"
set /a NumberOfSpaces=0
set /a Start=1
set /a Step=1
set /a Skip=0
set /a Keep=1

call :StringLength !String! , Length

if !Length! equ 0 goto End

set /a Stop=!Length!

FOR /L %%X IN (!Start!,!Step!,!Stop!) DO (

    call set Char=!!String:~!Skip!,!Keep!!!

    if "!Char!" == " " set /a NumberOfSpaces+=1
    
    set /a Skip+=1
    
)

:End

endlocal & if "%~2" equ "" (echo !NumberOfSpaces!) else set /a %~2=!NumberOfSpaces!

exit /B 0

::==============================================================================

:WordCount StrVar , [RtnVar]

setlocal EnableExtensions EnableDelayedExpansion

REM Not yet implemented.

endlocal

exit /B 0

::==============================================================================

:WordLength StrVar , WordNumber , [RtnVar_WordLen] , [RtnVar_StartPos] , [RtnVar_EndPos]

setlocal EnableExtensions EnableDelayedExpansion

REM Not yet implemented.

endlocal

exit /B 0

答案1

您的脚本还有许多需要改进的地方。不过,这只是对您问题的回答。

例如,:StringLength函数中的Length变量是局部的,因此在执行后!Length!不再定义:endlocal

endlocal & if "%~2" equ "" (echo !Length!) else set /a %~2=!Length!
rem                               ↑↑↑↑↑↑                    ↑↑↑↑↑↑

然而,%Length%仍然有效(定义在解析时间)所以线应该是

endlocal & if "%~2" equ "" (echo %Length%) else set /a %~2=%Length%

更多内容请阅读SETLOCAL设置选项来控制批处理文件中环境变量的可见性。以及后续EnableDelayedExpansion

延迟扩展将导致批处理文件中的变量在执行时而不是在解析时扩展,此选项通过命令打开SETLOCAL EnableDelayedExpansion

相关内容