2012-05-20 65 views

回答

3

一個簡單的方法是使用一個函數

@echo off 
set "myVar=abcdefg" 
call :Stringlength result myVar 
echo %result% 
exit /b 

:Stringlength <resultVar> <stringVar> 
( 
    setlocal EnableDelayedExpansion 
    set "s=!%~2!#" 
    set "len=0" 
    for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
     if "!s:~%%P,1!" NEQ "" ( 
      set /a "len+=%%P" 
      set "s=!s:~%%P!" 
     ) 
    ) 
) 
( 
    endlocal 
    set "%~1=%len%" 
    exit /b 
) 

這可以測量串爲最多8192個字符,作爲字符串的最大大小是8191個字節,這應該是足夠的。
第一個括號塊僅用於更多的性能。
需要第二個塊來將%len%值返回到endlocal barrier的後面。
主要思想是二進制搜索,在第一個循環中,字符串的s中的臨時副本是否被測試,如果它是否長於4096字節。
然後下一個測試將是2048或6144(= 2048 + 4096),所以len變量將在每個循環更精確一點。
經過13次循環後,len是準確的。

對於更快的strlen函數,你可以讀​​3210,它使用了一些更多的技巧。

還有一個批處理宏的解決方案,宏通常比批處理中的函數快得多。

@echo off 
call :loadMacros 
set "myVar=abcdefg" 
%$strlen% result myVar 
echo %result% 
exit /b 


:loadMacros 
set LF=^ 


::Above 2 blank lines are required - do not remove 
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^" 
:::: StrLen pResult pString 
set $strLen=for /L %%n in (1 1 2) do if %%n==2 (%\n% 
     for /F "tokens=1,2 delims=, " %%1 in ("!argv!") do (%\n% 
      set "str=A!%%~2!"%\n% 
       set "len=0"%\n% 
       for /l %%A in (12,-1,0) do (%\n% 
       set /a "len|=1<<%%A"%\n% 
       for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"%\n% 
      )%\n% 
       for %%v in (!len!) do endlocal^&if "%%~b" neq "" (set "%%~1=%%v") else echo %%v%\n% 
     ) %\n% 
) ELSE setlocal enableDelayedExpansion ^& set argv=, 

exit /b 

在dostips.com是對宏觀TECHNIC一些討論

+0

我敢肯定,這是比基本循環更快,但你正在假設最大字符串長度... – Anders

+0

什麼是函數中兩個主要塊的重點和它們的大括號? – Anders

+0

是的,我假定字符串不能超過8192字節,並且總是如此,因爲變量不能包含更多 – jeb

0

當你調用該函數,第二個參數應該是一個值,而不是一個參考:

call :Stringlength result %myVar% 
相關問題