Как посчитать символы в строке с помощью Batch? [закрыто]

Мне нужно посчитать символы введенной строки в пакетном режиме. Я не хочу использовать временные файлы. Можно ли это сделать без них? Если да, объяснения вашего кода будут с благодарностью. Спасибо ТАК!

Ответы на вопрос(2)

@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% значение за эндокальный барьер.
Основная идея - бинарный поиск, в первом цикле временная копия вs строки проверяется, если она длиннее 4096 байт или нет.
Тогда следующий тест будет с 2048 или 6144 (= 2048 + 4096), поэтомуlen переменная будет в каждом цикле чуть точнее.
После 13 циклов лен точно.

Для более быстрых функций вы можете прочитатьСтрлен повысил, который использует еще несколько трюков.

Существует также решение с пакетными макросами, макросы обычно намного быстрее, чем функции в пакетном режиме.

@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 есть некоторые обсуждения о макротехнике
1 Пакетный "макрос" с аргументами
2 макросы с добавленными параметрами

 20 мая 2012 г., 18:53
Почему первый блок дает лучшую производительность? Второй блок, вероятно, можно заменить на endlocal & amp; set ...
 20 мая 2012 г., 18:42
Я уверен, что это быстрее, чем простой цикл, но вы делаете предположения о максимальной длине строки ...
 Ivan Spajic20 мая 2012 г., 20:58
Может кто-нибудь объяснить мне все это? Я, кажется, совсем сбит с толку всем этим. Я хотел бы получить подробное объяснение сверху вниз. Спасибо!
 20 мая 2012 г., 18:43
В чем смысл двух основных блоков в функции и их фигурных скобок?
 20 мая 2012 г., 18:44
Да, я предполагаю, что строка не может быть длиннее 8192 байтов, и это всегда верно, поскольку переменная не может содержать больше

второй параметр должен быть значением, а не ссылкой:

call :Stringlength result %myVar%

Ваш ответ на вопрос