如何在批处理文件中获取字符串长度?

时间:2022-05-17 02:08:28

There doesn't appear to be an easy way to get the length of a string in a batch file. E.g.,

在批处理文件中,似乎没有一种简单的方法来获取字符串的长度。例如,

SET MY_STRING=abcdefg
SET /A MY_STRING_LEN=???

How would I find the string length of MY_STRING?

如何找到MY_STRING的字符串长度?

Bonus points if the string length function handles all possible characters in strings including escape characters, like this: !%^^()^!.

加分如果字符串长度函数处理所有可能的字符在字符串包括转义字符,像这样:! % ^ ^()^ !。

12 个解决方案

#1


70  

As there is no built in function for string length, you can write your own function like so:

由于字符串长度没有内置函数,您可以这样编写自己的函数:

@echo off
setlocal
set "myString=abcdef!%%^^()^!"
call :strlen result myString
echo %result%
goto :eof

:strlen <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
)

This function needs always 13 loops, instead of a simple strlen function which needs strlen-loops.
It handles all characters.

这个函数需要13个循环,而不是一个简单的strlen函数。它处理所有字符。

#2


24  

You can do it in two lines, fully in a batch file, by writing the string to a file and then getting the length of the file. You just have to subtract two bytes to account for the automatic CR+LF added to the end.

您可以通过将字符串写入文件,然后得到文件的长度,在两行中,完全在批处理文件中完成。你只需要减去2个字节,就可以算出自动CR+LF的结束。

Let's say your string is in a variable called strvar:

假设你的字符串在一个变量strvar:

ECHO %strvar%> tempfile.txt
FOR %%? IN (tempfile.txt) DO ( SET /A strlength=%%~z? - 2 )

The length of the string is now in a variable called strlength.

字符串的长度现在在一个名为strlength的变量中。

In slightly more detail:

更详细的:

  • FOR %%? IN (filename) DO ( ... : gets info about a file
  • % % ?在(文件名)中做(……:获取一个文件的信息。
  • SET /A [variable]=[expression] : evaluate the expression numerically
  • SET /A [variable]=[表达式]:数值计算表达式。
  • %%~z? : Special expression to get the length of the file
  • % % ~ z ?:用于获取文件长度的特殊表达式。

To mash the whole command in one line:

将整条命令合并成一行:

ECHO %strvar%>x&FOR %%? IN (x) DO SET /A strlength=%%~z? - 2&del x

#3


18  

I prefer jeb's accepted answer - it is the fastest known solution and the one I use in my own scripts. (Actually there are a few additional optimizations bandied about on DosTips, but I don't think they are worth it)

我更喜欢jeb的被接受的答案——它是已知的最快的解决方案,也是我在自己的脚本中使用的解决方案。(实际上,在DosTips上有一些额外的优化,但我认为它们不值得)

But it is fun to come up with new efficient algorithms. Here is a new algorithm that uses the FINDSTR /O option:

但是想出新的高效的算法是很有趣的。下面是一个使用FINDSTR /O选项的新算法:

@echo off
setlocal
set "test=Hello world!"

:: Echo the length of TEST
call :strLen test

:: Store the length of TEST in LEN
call :strLen test len
echo len=%len%
exit /b

:strLen  strVar  [rtnVar]
setlocal disableDelayedExpansion
set len=0
if defined %~1 for /f "delims=:" %%N in (
  '"(cmd /v:on /c echo(!%~1!&echo()|findstr /o ^^"'
) do set /a "len=%%N-3"
endlocal & if "%~2" neq "" (set %~2=%len%) else echo %len%
exit /b

The code subtracts 3 because the parser juggles the command and adds a space before CMD /V /C executes it. It can be prevented by using (echo(!%~1!^^^).

因为解析器在CMD /V /C执行它之前添加了一个空格,所以代码会减缩3。但可以被使用(echo(% ~ 1 ! ^ ^ ^)。


For those that want the absolute fastest performance possible, jeb's answer can be adopted for use as a batch "macro" with arguments. This is an advanced batch technique devloped over at DosTips that eliminates the inherently slow process of CALLing a :subroutine. You can get more background on the concepts behind batch macros here, but that link uses a more primitive, less desirable syntax.

对于那些想要绝对最快的性能的人来说,jeb的答案可以作为一个批量的“宏”来使用参数。这是一种先进的批处理技术,在DosTips上进行了devloped,消除了调用a:子例程的固有的缓慢过程。在这里,您可以获得更多关于批处理宏的概念的背景知识,但是这个链接使用了更原始的、不那么理想的语法。

Below is an optimized @strLen macro, with examples showing differences between the macro and :subroutine usage, as well as differences in performance.

下面是一个优化的@strLen宏,示例显示了宏和:子例程的用法,以及性能上的差异。

@echo off
setlocal disableDelayedExpansion

:: -------- Begin macro definitions ----------
set ^"LF=^
%= This creates a variable containing a single linefeed (0x0A) character =%
^"
:: Define %\n% to effectively issue a newline with line continuation
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"

:: @strLen  StrVar  [RtnVar]
::
::   Computes the length of string in variable StrVar
::   and stores the result in variable RtnVar.
::   If RtnVar is is not specified, then prints the length to stdout.
::
set @strLen=for %%. in (1 2) do if %%.==2 (%\n%
  for /f "tokens=1,2 delims=, " %%1 in ("!argv!") do ( endlocal%\n%
    set "s=A!%%~1!"%\n%
    set "len=0"%\n%
    for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (%\n%
      if "!s:~%%P,1!" neq "" (%\n%
        set /a "len+=%%P"%\n%
        set "s=!s:~%%P!"%\n%
      )%\n%
    )%\n%
    for %%V in (!len!) do endlocal^&if "%%~2" neq "" (set "%%~2=%%V") else echo %%V%\n%
  )%\n%
) else setlocal enableDelayedExpansion^&setlocal^&set argv=,

:: -------- End macro definitions ----------

:: Print out definition of macro
set @strLen

:: Demonstrate usage

set "testString=this has a length of 23"

echo(
echo Testing %%@strLen%% testString
%@strLen% testString

echo(
echo Testing call :strLen testString
call :strLen testString

echo(
echo Testing %%@strLen%% testString rtn
set "rtn="
%@strLen% testString rtn
echo rtn=%rtn%

echo(
echo Testing call :strLen testString rtn
set "rtn="
call :strLen testString rtn
echo rtn=%rtn%

echo(
echo Measuring %%@strLen%% time:
set "t0=%time%"
for /l %%N in (1 1 1000) do %@strlen% testString testLength
set "t1=%time%"
call :printTime

echo(
echo Measuring CALL :strLen time:
set "t0=%time%"
for /l %%N in (1 1 1000) do call :strLen testString testLength
set "t1=%time%"
call :printTime
exit /b


:strlen  StrVar  [RtnVar]
::
:: Computes the length of string in variable StrVar
:: and stores the result in variable RtnVar.
:: If RtnVar is is not specified, then prints the length to stdout.
::
(
  setlocal EnableDelayedExpansion
  set "s=A!%~1!"
  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
  if "%~2" equ "" (echo %len%) else set "%~2=%len%"
  exit /b
)

:printTime
setlocal
for /f "tokens=1-4 delims=:.," %%a in ("%t0: =0%") do set /a "t0=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100
for /f "tokens=1-4 delims=:.," %%a in ("%t1: =0%") do set /a "t1=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100
set /a tm=t1-t0
if %tm% lss 0 set /a tm+=24*60*60*100
echo %tm:~0,-2%.%tm:~-2% msec
exit /b

-- Sample Output --

示例输出,

@strLen=for %. in (1 2) do if %.==2 (
  for /f "tokens=1,2 delims=, " %1 in ("!argv!") do ( endlocal
    set "s=A!%~1!"
    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!"
      )
    )
    for %V in (!len!) do endlocal&if "%~2" neq "" (set "%~2=%V") else echo %V
  )
) else setlocal enableDelayedExpansion&setlocal&set argv=,

Testing %@strLen% testString
23

Testing call :strLen testString
23

Testing %@strLen% testString rtn
rtn=23

Testing call :strLen testString rtn
rtn=23

Measuring %@strLen% time:
1.93 msec

Measuring CALL :strLen time:
7.08 msec

#4


6  

The first few lines are simply to demonstrate the :strLen function.

前几行简单地演示了:strLen函数。

@echo off
set "strToMeasure=This is a string"
call :strLen strToMeasure strlen
echo.String is %strlen% characters long
exit /b

:strLen
setlocal enabledelayedexpansion
:strLen_Loop
  if not "!%1:~%len%!"=="" set /A len+=1 & goto :strLen_Loop
(endlocal & set %2=%len%)
goto :eof

Of course, this is not quite as efficient at the "13 loop" version provided by jeb. But it is easier to understand, and your 3GHz computer can slip through a few thousand iterations in a small fraction of a second.

当然,这在jeb提供的“13循环”版本中并没有那么高效。但它更容易理解,而你的3GHz电脑在一小段时间内就能通过几千次迭代。

#5


5  

Yes, of course there's an easy way, using vbscript (or powershell).

是的,当然有一个简单的方法,使用vbscript(或powershell)。

WScript.Echo Len( WScript.Arguments(0) )

save this as strlen.vbs and on command line

保存这个strlen。vbs和命令行。

c:\test> cscript //nologo strlen.vbs "abcd"

Use a for loop to capture the result ( or use vbscript entirely for your scripting task)

使用for循环来捕获结果(或者完全使用vbscript来完成脚本任务)

Certainly beats having to create cumbersome workarounds using batch and there's no excuse not to use it since vbscript is available with each Windows distribution ( and powershell in later).

当然,要使用批处理来创建笨拙的工作区,没有理由不使用它,因为vbscript可以在每个Windows发行版(以及稍后的powershell)中使用。

#6


3  

If you are on Windows Vista +, then try this Powershell method:

如果你在Windows Vista +上,试试这个Powershell方法:

For /F %%L in ('Powershell $Env:MY_STRING.Length') do (
    Set MY_STRING_LEN=%%L
)

or alternatively:

或者:

Powershell $Env:MY_STRING.Length > %Temp%\TmpFile.txt
Set /p MY_STRING_LEN = < %Temp%\TmpFile.txt
Del %Temp%\TmpFile.txt

I'm on Windows 7 x64 and this is working for me.

我在Windows 7 x64上,这是为我工作。

#7


2  

I like the two line approach of jmh_gr.

我喜欢jmh_gr的两行方法。

It won't work with single digit numbers unless you put () around the portion of the command before the redirect. since 1> is a special command "Echo is On" will be redirected to the file.

除非您在重定向之前在命令的部分周围加上(),否则不会使用单个数字。由于>是一个特殊的命令,“Echo is On”将被重定向到文件。

This example should take care of single digit numbers but not the other special characters such as < that may be in the string.

这个示例应该注意单个数字的数字,而不是其他特殊字符,例如 <可能在字符串中。< p>

(ECHO %strvar%)> tempfile.txt

#8


2  

Just found ULTIMATE solution:

只是找到最终解决方案:

set "MYSTRING=abcdef!%%^^()^!"
(echo "%MYSTRING%" & echo.) | findstr /O . | more +1 | (set /P RESULT= & call exit /B %%RESULT%%)
set /A STRLENGTH=%ERRORLEVEL%-5
echo string "%MYSTRING%" length = %STRLENGTH%

The output is:

的输出是:

string "abcdef!%^^()^!" length = 14

It handles escape characters, an order of magnitude simpler then most solutions above, and contains no loops, magic numbers, DelayedExpansion, temp files, etc.

它处理转义字符,一个简单的数量级,然后是上面的大多数解决方案,不包含任何循环、魔术数字、DelayedExpansion、temp文件等等。

In case usage outside batch script (mean putting commands to console manually), replace %%RESULT%% key with %RESULT%.

在使用外部批处理脚本的情况下,用%% %% %% %% %% %% %% %% %%的%% %% %% %% %% %% %% %% %% %% %% %% %% %%。

If needed, %ERRORLEVEL% variable could be set to FALSE using any NOP command, e.g. echo. >nul

如果需要,%ERRORLEVEL%变量可以使用任何NOP命令设置为FALSE,例如echo。>空

#9


1  

Just another batch script to calculate the length of a string, in just a few lines. It may not be the fastest, but it's pretty small. The subroutine ":len" returns the length in the second parameter. The first parameter is the actual string being analysed. Please note - special characters must be escaped, that is the case with any string in the batch file.

仅仅是用几行代码来计算字符串长度的另一个批处理脚本。它可能不是最快的,但它很小。子例程“:len”返回第二个参数中的长度。第一个参数是正在分析的实际字符串。请注意——必须转义特殊字符,即批处理文件中的任何字符串。

@echo off
setlocal
call :len "Sample text" a
echo The string has %a% characters.
endlocal
goto :eof

:len <string> <length_variable> - note: string must be quoted because it may have spaces
setlocal enabledelayedexpansion&set l=0&set str=%~1
:len_loop
set x=!str:~%l%,1!&if not defined x (endlocal&set "%~2=%l%"&goto :eof)
set /a l=%l%+1&goto :len_loop

#10


1  

@echo off & setlocal EnableDelayedExpansion
set Var=finding the length of strings
for /l %%A in (0,1,10000) do if not "%Var%"=="!Var:~0,%%A!" (set /a Length+=1) else (echo !Length! & pause & exit /b)

set the var to whatever you want to find the length of it or change it to set /p var= so that the user inputs it. Putting this here for future reference.

将var设置为您想要查找的长度,或者将其更改为set /p var=以便用户输入它。把这个放在这里,以备将来参考。

#11


0  

@echo off
::   warning doesn't like * ( in mystring

setlocal enabledelayedexpansion 

set mystring=this is my string to be counted forty one

call :getsize %mystring%
echo count=%count% of "%mystring%" 

set mystring=this is my string to be counted

call :getsize %mystring%

echo count=%count% of "%mystring%" 

set mystring=this is my string
call :getsize %mystring%

echo count=%count% of "%mystring%" 
echo.
pause
goto :eof

:: Get length of mystring line ######### subroutine getsize ########

:getsize

set count=0

for /l %%n in (0,1,2000) do (

    set chars=

    set chars=!mystring:~%%n!

    if defined chars set /a count+=1
)
goto :eof

:: ############## end of subroutine getsize ########################

#12


0  

I want to preface this by saying I don't know much about writing code/script/etc. but thought I'd share a solution I seem to have come up with. Most of the responses here kinda went over my head, so I was curious to know if what I've written is comparable.

我想说的是,我不太懂写代码/脚本等等。但我想我应该分享一个我似乎已经想到的解决方案。这里的大部分回答都超出了我的理解范围,所以我很想知道我写的东西是否具有可比性。

@echo off

set stringLength=0

call:stringEater "It counts most characters"
echo %stringLength%
echo.&pause&goto:eof

:stringEater
set var=%~1
:subString
set n=%var:~0,1%
if "%n%"=="" (
        goto:eof
    ) else if "%n%"==" " (
        set /a stringLength=%stringLength%+1
    ) else (
        set /a stringLength=%stringLength%+1
    )
set var=%var:~1,1000%
if "%var%"=="" (
        goto:eof
    ) else (
        goto subString
    )

goto:eof

#1


70  

As there is no built in function for string length, you can write your own function like so:

由于字符串长度没有内置函数,您可以这样编写自己的函数:

@echo off
setlocal
set "myString=abcdef!%%^^()^!"
call :strlen result myString
echo %result%
goto :eof

:strlen <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
)

This function needs always 13 loops, instead of a simple strlen function which needs strlen-loops.
It handles all characters.

这个函数需要13个循环,而不是一个简单的strlen函数。它处理所有字符。

#2


24  

You can do it in two lines, fully in a batch file, by writing the string to a file and then getting the length of the file. You just have to subtract two bytes to account for the automatic CR+LF added to the end.

您可以通过将字符串写入文件,然后得到文件的长度,在两行中,完全在批处理文件中完成。你只需要减去2个字节,就可以算出自动CR+LF的结束。

Let's say your string is in a variable called strvar:

假设你的字符串在一个变量strvar:

ECHO %strvar%> tempfile.txt
FOR %%? IN (tempfile.txt) DO ( SET /A strlength=%%~z? - 2 )

The length of the string is now in a variable called strlength.

字符串的长度现在在一个名为strlength的变量中。

In slightly more detail:

更详细的:

  • FOR %%? IN (filename) DO ( ... : gets info about a file
  • % % ?在(文件名)中做(……:获取一个文件的信息。
  • SET /A [variable]=[expression] : evaluate the expression numerically
  • SET /A [variable]=[表达式]:数值计算表达式。
  • %%~z? : Special expression to get the length of the file
  • % % ~ z ?:用于获取文件长度的特殊表达式。

To mash the whole command in one line:

将整条命令合并成一行:

ECHO %strvar%>x&FOR %%? IN (x) DO SET /A strlength=%%~z? - 2&del x

#3


18  

I prefer jeb's accepted answer - it is the fastest known solution and the one I use in my own scripts. (Actually there are a few additional optimizations bandied about on DosTips, but I don't think they are worth it)

我更喜欢jeb的被接受的答案——它是已知的最快的解决方案,也是我在自己的脚本中使用的解决方案。(实际上,在DosTips上有一些额外的优化,但我认为它们不值得)

But it is fun to come up with new efficient algorithms. Here is a new algorithm that uses the FINDSTR /O option:

但是想出新的高效的算法是很有趣的。下面是一个使用FINDSTR /O选项的新算法:

@echo off
setlocal
set "test=Hello world!"

:: Echo the length of TEST
call :strLen test

:: Store the length of TEST in LEN
call :strLen test len
echo len=%len%
exit /b

:strLen  strVar  [rtnVar]
setlocal disableDelayedExpansion
set len=0
if defined %~1 for /f "delims=:" %%N in (
  '"(cmd /v:on /c echo(!%~1!&echo()|findstr /o ^^"'
) do set /a "len=%%N-3"
endlocal & if "%~2" neq "" (set %~2=%len%) else echo %len%
exit /b

The code subtracts 3 because the parser juggles the command and adds a space before CMD /V /C executes it. It can be prevented by using (echo(!%~1!^^^).

因为解析器在CMD /V /C执行它之前添加了一个空格,所以代码会减缩3。但可以被使用(echo(% ~ 1 ! ^ ^ ^)。


For those that want the absolute fastest performance possible, jeb's answer can be adopted for use as a batch "macro" with arguments. This is an advanced batch technique devloped over at DosTips that eliminates the inherently slow process of CALLing a :subroutine. You can get more background on the concepts behind batch macros here, but that link uses a more primitive, less desirable syntax.

对于那些想要绝对最快的性能的人来说,jeb的答案可以作为一个批量的“宏”来使用参数。这是一种先进的批处理技术,在DosTips上进行了devloped,消除了调用a:子例程的固有的缓慢过程。在这里,您可以获得更多关于批处理宏的概念的背景知识,但是这个链接使用了更原始的、不那么理想的语法。

Below is an optimized @strLen macro, with examples showing differences between the macro and :subroutine usage, as well as differences in performance.

下面是一个优化的@strLen宏,示例显示了宏和:子例程的用法,以及性能上的差异。

@echo off
setlocal disableDelayedExpansion

:: -------- Begin macro definitions ----------
set ^"LF=^
%= This creates a variable containing a single linefeed (0x0A) character =%
^"
:: Define %\n% to effectively issue a newline with line continuation
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"

:: @strLen  StrVar  [RtnVar]
::
::   Computes the length of string in variable StrVar
::   and stores the result in variable RtnVar.
::   If RtnVar is is not specified, then prints the length to stdout.
::
set @strLen=for %%. in (1 2) do if %%.==2 (%\n%
  for /f "tokens=1,2 delims=, " %%1 in ("!argv!") do ( endlocal%\n%
    set "s=A!%%~1!"%\n%
    set "len=0"%\n%
    for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (%\n%
      if "!s:~%%P,1!" neq "" (%\n%
        set /a "len+=%%P"%\n%
        set "s=!s:~%%P!"%\n%
      )%\n%
    )%\n%
    for %%V in (!len!) do endlocal^&if "%%~2" neq "" (set "%%~2=%%V") else echo %%V%\n%
  )%\n%
) else setlocal enableDelayedExpansion^&setlocal^&set argv=,

:: -------- End macro definitions ----------

:: Print out definition of macro
set @strLen

:: Demonstrate usage

set "testString=this has a length of 23"

echo(
echo Testing %%@strLen%% testString
%@strLen% testString

echo(
echo Testing call :strLen testString
call :strLen testString

echo(
echo Testing %%@strLen%% testString rtn
set "rtn="
%@strLen% testString rtn
echo rtn=%rtn%

echo(
echo Testing call :strLen testString rtn
set "rtn="
call :strLen testString rtn
echo rtn=%rtn%

echo(
echo Measuring %%@strLen%% time:
set "t0=%time%"
for /l %%N in (1 1 1000) do %@strlen% testString testLength
set "t1=%time%"
call :printTime

echo(
echo Measuring CALL :strLen time:
set "t0=%time%"
for /l %%N in (1 1 1000) do call :strLen testString testLength
set "t1=%time%"
call :printTime
exit /b


:strlen  StrVar  [RtnVar]
::
:: Computes the length of string in variable StrVar
:: and stores the result in variable RtnVar.
:: If RtnVar is is not specified, then prints the length to stdout.
::
(
  setlocal EnableDelayedExpansion
  set "s=A!%~1!"
  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
  if "%~2" equ "" (echo %len%) else set "%~2=%len%"
  exit /b
)

:printTime
setlocal
for /f "tokens=1-4 delims=:.," %%a in ("%t0: =0%") do set /a "t0=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100
for /f "tokens=1-4 delims=:.," %%a in ("%t1: =0%") do set /a "t1=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100
set /a tm=t1-t0
if %tm% lss 0 set /a tm+=24*60*60*100
echo %tm:~0,-2%.%tm:~-2% msec
exit /b

-- Sample Output --

示例输出,

@strLen=for %. in (1 2) do if %.==2 (
  for /f "tokens=1,2 delims=, " %1 in ("!argv!") do ( endlocal
    set "s=A!%~1!"
    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!"
      )
    )
    for %V in (!len!) do endlocal&if "%~2" neq "" (set "%~2=%V") else echo %V
  )
) else setlocal enableDelayedExpansion&setlocal&set argv=,

Testing %@strLen% testString
23

Testing call :strLen testString
23

Testing %@strLen% testString rtn
rtn=23

Testing call :strLen testString rtn
rtn=23

Measuring %@strLen% time:
1.93 msec

Measuring CALL :strLen time:
7.08 msec

#4


6  

The first few lines are simply to demonstrate the :strLen function.

前几行简单地演示了:strLen函数。

@echo off
set "strToMeasure=This is a string"
call :strLen strToMeasure strlen
echo.String is %strlen% characters long
exit /b

:strLen
setlocal enabledelayedexpansion
:strLen_Loop
  if not "!%1:~%len%!"=="" set /A len+=1 & goto :strLen_Loop
(endlocal & set %2=%len%)
goto :eof

Of course, this is not quite as efficient at the "13 loop" version provided by jeb. But it is easier to understand, and your 3GHz computer can slip through a few thousand iterations in a small fraction of a second.

当然,这在jeb提供的“13循环”版本中并没有那么高效。但它更容易理解,而你的3GHz电脑在一小段时间内就能通过几千次迭代。

#5


5  

Yes, of course there's an easy way, using vbscript (or powershell).

是的,当然有一个简单的方法,使用vbscript(或powershell)。

WScript.Echo Len( WScript.Arguments(0) )

save this as strlen.vbs and on command line

保存这个strlen。vbs和命令行。

c:\test> cscript //nologo strlen.vbs "abcd"

Use a for loop to capture the result ( or use vbscript entirely for your scripting task)

使用for循环来捕获结果(或者完全使用vbscript来完成脚本任务)

Certainly beats having to create cumbersome workarounds using batch and there's no excuse not to use it since vbscript is available with each Windows distribution ( and powershell in later).

当然,要使用批处理来创建笨拙的工作区,没有理由不使用它,因为vbscript可以在每个Windows发行版(以及稍后的powershell)中使用。

#6


3  

If you are on Windows Vista +, then try this Powershell method:

如果你在Windows Vista +上,试试这个Powershell方法:

For /F %%L in ('Powershell $Env:MY_STRING.Length') do (
    Set MY_STRING_LEN=%%L
)

or alternatively:

或者:

Powershell $Env:MY_STRING.Length > %Temp%\TmpFile.txt
Set /p MY_STRING_LEN = < %Temp%\TmpFile.txt
Del %Temp%\TmpFile.txt

I'm on Windows 7 x64 and this is working for me.

我在Windows 7 x64上,这是为我工作。

#7


2  

I like the two line approach of jmh_gr.

我喜欢jmh_gr的两行方法。

It won't work with single digit numbers unless you put () around the portion of the command before the redirect. since 1> is a special command "Echo is On" will be redirected to the file.

除非您在重定向之前在命令的部分周围加上(),否则不会使用单个数字。由于>是一个特殊的命令,“Echo is On”将被重定向到文件。

This example should take care of single digit numbers but not the other special characters such as < that may be in the string.

这个示例应该注意单个数字的数字,而不是其他特殊字符,例如 <可能在字符串中。< p>

(ECHO %strvar%)> tempfile.txt

#8


2  

Just found ULTIMATE solution:

只是找到最终解决方案:

set "MYSTRING=abcdef!%%^^()^!"
(echo "%MYSTRING%" & echo.) | findstr /O . | more +1 | (set /P RESULT= & call exit /B %%RESULT%%)
set /A STRLENGTH=%ERRORLEVEL%-5
echo string "%MYSTRING%" length = %STRLENGTH%

The output is:

的输出是:

string "abcdef!%^^()^!" length = 14

It handles escape characters, an order of magnitude simpler then most solutions above, and contains no loops, magic numbers, DelayedExpansion, temp files, etc.

它处理转义字符,一个简单的数量级,然后是上面的大多数解决方案,不包含任何循环、魔术数字、DelayedExpansion、temp文件等等。

In case usage outside batch script (mean putting commands to console manually), replace %%RESULT%% key with %RESULT%.

在使用外部批处理脚本的情况下,用%% %% %% %% %% %% %% %% %%的%% %% %% %% %% %% %% %% %% %% %% %% %% %%。

If needed, %ERRORLEVEL% variable could be set to FALSE using any NOP command, e.g. echo. >nul

如果需要,%ERRORLEVEL%变量可以使用任何NOP命令设置为FALSE,例如echo。>空

#9


1  

Just another batch script to calculate the length of a string, in just a few lines. It may not be the fastest, but it's pretty small. The subroutine ":len" returns the length in the second parameter. The first parameter is the actual string being analysed. Please note - special characters must be escaped, that is the case with any string in the batch file.

仅仅是用几行代码来计算字符串长度的另一个批处理脚本。它可能不是最快的,但它很小。子例程“:len”返回第二个参数中的长度。第一个参数是正在分析的实际字符串。请注意——必须转义特殊字符,即批处理文件中的任何字符串。

@echo off
setlocal
call :len "Sample text" a
echo The string has %a% characters.
endlocal
goto :eof

:len <string> <length_variable> - note: string must be quoted because it may have spaces
setlocal enabledelayedexpansion&set l=0&set str=%~1
:len_loop
set x=!str:~%l%,1!&if not defined x (endlocal&set "%~2=%l%"&goto :eof)
set /a l=%l%+1&goto :len_loop

#10


1  

@echo off & setlocal EnableDelayedExpansion
set Var=finding the length of strings
for /l %%A in (0,1,10000) do if not "%Var%"=="!Var:~0,%%A!" (set /a Length+=1) else (echo !Length! & pause & exit /b)

set the var to whatever you want to find the length of it or change it to set /p var= so that the user inputs it. Putting this here for future reference.

将var设置为您想要查找的长度,或者将其更改为set /p var=以便用户输入它。把这个放在这里,以备将来参考。

#11


0  

@echo off
::   warning doesn't like * ( in mystring

setlocal enabledelayedexpansion 

set mystring=this is my string to be counted forty one

call :getsize %mystring%
echo count=%count% of "%mystring%" 

set mystring=this is my string to be counted

call :getsize %mystring%

echo count=%count% of "%mystring%" 

set mystring=this is my string
call :getsize %mystring%

echo count=%count% of "%mystring%" 
echo.
pause
goto :eof

:: Get length of mystring line ######### subroutine getsize ########

:getsize

set count=0

for /l %%n in (0,1,2000) do (

    set chars=

    set chars=!mystring:~%%n!

    if defined chars set /a count+=1
)
goto :eof

:: ############## end of subroutine getsize ########################

#12


0  

I want to preface this by saying I don't know much about writing code/script/etc. but thought I'd share a solution I seem to have come up with. Most of the responses here kinda went over my head, so I was curious to know if what I've written is comparable.

我想说的是,我不太懂写代码/脚本等等。但我想我应该分享一个我似乎已经想到的解决方案。这里的大部分回答都超出了我的理解范围,所以我很想知道我写的东西是否具有可比性。

@echo off

set stringLength=0

call:stringEater "It counts most characters"
echo %stringLength%
echo.&pause&goto:eof

:stringEater
set var=%~1
:subString
set n=%var:~0,1%
if "%n%"=="" (
        goto:eof
    ) else if "%n%"==" " (
        set /a stringLength=%stringLength%+1
    ) else (
        set /a stringLength=%stringLength%+1
    )
set var=%var:~1,1000%
if "%var%"=="" (
        goto:eof
    ) else (
        goto subString
    )

goto:eof